Aprender la primavera en la práctica, el objetivo final de esta serie es completar un proyecto que implementa la función de registro e inicio de sesión del usuario.
El proceso básico esperado es el siguiente:
1. Registre el sitio web del usuario, complete el nombre de usuario, la contraseña, el correo electrónico y la información del número de teléfono móvil, y devuelva OK después de depositarlo en la base de datos en segundo plano. (Aprenda los conocimientos básicos de COI, MyBatis, SpringMVC, Verificación de datos de formulario, carga de archivos, etc.)
2. El servidor envía correos electrónicos de forma asincrónica al usuario registrado. (Aprenda cola de mensajes)
3. Inicio de sesión del usuario. (Aprendiendo caché, seguridad de primavera)
4. Otros.
Estudiar y resumir, y actualizar de vez en cuando. El entorno del proyecto es IntelliJ + Spring4.
1. Trabajo de preparación.
1. Cree una base de datos y tablas en MySQL.
2. Cree un proyecto Maven WebApp en IntelliJ.
(1) Importar los paquetes de dependencia requeridos en pom.xml.
<? xml versión = "1.0" encoding = "utf-8"?> <Proyecto xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/xmlschemainstance" xsi: schemalocatation = "http://maven.apache.org/pom/4.0.0.0.0. http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelversion>4.0.0</modelversion><groupid>com.everseeker</groupid><Artifactid>register> Maven WebApp </name> <url> http://maven.apache.org </sl> <properties> <spring.version> 4.3.1.release </spring.version> </propiedades> <pendencies> <!-Spring Core, Contexto-> <Spendency> <MoupRid> org.springframework </proupid> <artifactid> Spring-Context </arfactid> <verserse> $ {Spring.version} </verversion> </pendency> <ependency> <grupo> org.springframework </spopeD> <Atifa CTID> Spring-Context-Support </arfactiD> <versever> $ {spring.version} </verversion> </pendency> <pendency> <proupid> org.springframework </groupid> <artifactid> spring-core </artifactid> <versión> $ {spring.version} </eVe rsion> </Dependency> <Spendency> <MoupRid> org.springframework </groupid> <artifactid> spring-beans </artifactid> <versers> $ {spring.version} </versión> </pendency> <!-test-> <pendency> <proupid> junit </proupid> <ar tifactid> Junit </arfactid> <verververs> 4.12 </verversion> <!-<cope> test </pope>-> </pepertency> <pepertency> <grupoD> org.springframework </proupid> <artifactId> spring-test </arfactid> <versión> $ {spring.version} </vee rsion> </pendency> <!-SpringMvc-> <Spendency> <MoupRid> org.springframework </uproupid> <arifactid> spring-webmvc </artifactid> <versión> $ {spring.version} </version> </pendency> <epardency> <proupid> org.springfr Amework </proupid> <artifactid> spring-web </artifactid> <versión> $ {spring.version} </versión> </pendency> <pendency> <grupid> javax.validation </groupid> <artifactID> validation-api </artifactid> <PROPELACIÓN 1.1.0.0.FINE al </verse> </pendency> <pendency> <uproupid> org.hibernate </groupid> <artifactid> hibernate-validator </arfactid> <versión> 5.2.4.final </verversion> </pendency> <!-servlet-> <pendency> <proupid> javax.servlet < /Groupid><Artifactid>Javax.Servlet-api</artifactid><version>3.1.0</version></Dependency><dependency><Groupid>Javax.servlet</Groupid><Artifactid>jstl</Artifactid><version>1.2</version></dependency> +-Mstysql. myBatis-> <Spendency> <MoupRid> org.springFramework </groupid> <artifactid> spring-jdbc </arfactid> <versers> $ {spring.version} </versión> </pendency> <Spendency> <MoupRupId> mysql </groupId> <AtifactId> mysql-connector-java </art de/artfact </artfact </arthifact </groupId> <AtifactId> mysql-connector-java </art de/artfact </artifact </suproupId> <AtifactId> mysql-connector-java </art de/artfact </artfact </arthup ID> <Versión> 6.0.3 </Versión> </pendency> <Spendency> <MoupRoid> org.mybatis </uproupid> <arifactid> mybatis </arfactid> <versers> 3.4.1 </verversion> </pendency> <pendency> <uproupid> org.mybatis </proupid> <artifactid> mybatis-spring </art </art </art </art ifactid> <versión> 1.3.0 </verververy> </pendency> <ependency> <proupid> c3p0 </groupid> <artifactid> c3p0 </artifactid> <versión> 0.1.1.2 </versión> </pendency> </pendencs> <dontent> <inalname> java_config_web </finalName> <glugins <glugins <glugins <glugin n> <MoupRid> org.apache.maven.plugins </proupid> <artifactID> maven-war-plugin </arifactid> <verserse> 2.2 </versewers> <foacturation> <sidOnmissingWebxml> false </failonMissingWebxml> </figuration> </tugin> </glugins> </build> </build> </build> </build> </build> </build> </build> (2) La estructura del directorio del proyecto es la siguiente:
2. Mybatis
1. Configure la información básica de la base de datos MySQL.
# Databasedb.mysql.driverClass = com.mysql.jdbc.driverdb.mysql.jdbcurl = jdbc: mysql: // localhost: 3306/registro_notice? UseUnicode = true y caracteres = utf-8 & iModmultIrliqueries = trueDb.mysql.user = rootDb.myStysQlysql.mytb.morthaldb.lytb.lytbaldb.daldbal 333db.minpoolSize = 10db.maxpoolSize = 100db.initialPoolSize = 20db.maxidletime = 60db.acquireIncrement = 5db.maxStatements = 100db.idleconnectionTeStperiod = 60db.acquireretrettempts = 30db.BreakAfterAracreirefailure = Truedb.testConnectionOncheckout = falsedb.properties
2. Configure mybatis.xml y spring-mybatis.xml.
<? xml versión = "1.0" encoding = "utf-8"?> < Alias-> <Pyypealiases> <!-Elija uno de los siguientes dos métodos. Método 1: Use Typealias para establecer alias para una sola clase. -> <!-<typealias type = "com.everseeker.entity.user" alias = "user" /> --- Método 2: Use el paquete para establecer alias para todas las clases debajo del paquete. La regla predeterminada es com.everseeker.entity.user está configurado en el usuario y elimina el nombre del paquete anterior. -> <paquete name = "com.everseeker.entity" /></typealiases></configuration>mybatis.xml<?xml versión = "1.0" coding = "utf-8"?> <frijoles xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema -instance" xmlns: context = "http://wwww.springframe.org /schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:p="http://www.springframework.org/schema/p"xsi:schemalocation="httttp://wwwww.org ringframework.org/schema/Beansshttp://www.springframework.org/schema/Beans/spring-Beanss.xsdhttp://www.spring framework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--- La introducción del archivo db.properties en este archivo puede garantizar que el valor correspondiente se pueda encontrar en la configuración posterior, como $ {db.mysql.drivullass}, de lo contrario, si un colega cargue directamente db.properties y spring-mybatis.xml en el programa de inicio de los programas, lo que no se puede garantizar que se produzca en el programa de db. Error-> <context: Property-placeholder ubicación = "classpath: db.properties"/> <!-Configuración de fuente de datos C3P0 tiene 2 paquetes de clase de implementación de fuente de datos comunes, uno es Apache DBCP (org.apache.commons.dbcp.basicdataSource), y el otro es C3P0. -> <bean id = "dataSource" destruye-method = "cerrar"> <propiedad name = "controlador de controlador" valor = "$ {db.mysql.driverclass}" /> <propiedad name = "jdbcurl" valor = "$ {db.mysql.jdbcurl}" /> <name de propiedad = "user" user = "$ {db.mysql" "" /> <Property Name = "Password" Value = "$ {db.mysql.password}" /> <!-El número mínimo de conexiones retenidas en el grupo de conexión. -> <propiedad name = "minpoolSize" value = "$ {db.minpoolsize}" /> <!-El número máximo de conexiones retenidas en el grupo de conexión. Valor predeterminado: 15-> <propiedad name = "maxpoolSize" value = "$ {db.maxpoolSize}" /> <!-El número de conexiones obtenidas durante la inicialización debe estar entre MinpoolSize y MaxpoolSize. Valor predeterminado: 3-> <Property name = "InitialPoolSize" Value = "$ {db.initialpoolSize}" /> <!-Tiempo libre máximo, si no se usa dentro de los 60 segundos, la conexión se descartará. Si es 0, nunca se descartará. Valor predeterminado: 0-> <Property name = "maxidletime" value = "$ {db.maxidletime}" /> <!-El número de conexiones obtenidas por C3P0 al mismo tiempo al mismo tiempo cuando la conexión en el grupo de conexión se agota. Valor predeterminado: 3-> <Property name = "adquirincrement" value = "$ {db.acquireincrement}" /> <!-Los parámetros estándar de JDBC se utilizan para controlar el número de equipos preparados en la fuente de datos. Pero porque las declaraciones precache pertenecen a una sola conexión en lugar de todo el grupo de conexión. Por lo tanto, establecer este parámetro requiere considerar muchos factores. Si tanto MaxStatements como MaxStatementsPerConnection son 0, el caché está cerrado. Valor predeterminado: 0-> <Property Name = "MaxStatements" value = "$ {db.maxStatements}" /> <!-Verifique todas las conexiones en el grupo de conexión cada 60 segundos. Valor predeterminado: 0-> <Property name = "idleconnectionTestperiod" value = "$ {db.idleconnectionTestperiod}" /> <!-Define el número de intentos repetidos después de que una nueva conexión no se recuperó de la base de datos. Valor predeterminado: 30-> <Property name = "adquireretryAttempts" value = "$ {db.acquireretryAttempts}" /> <!-Adquirir una conexión hará que todos los subprocesos que esperan que el grupo de conexión obtenga la conexión que lance una excepción. Sin embargo, la fuente de datos sigue siendo válida y continúa intentando obtener la conexión la próxima vez que llame a getConnection (). Si se establece en True, la fuente de datos declarará que se ha desconectado y cerrado permanentemente después de los intentos fallidos de obtener la conexión. Predeterminado: falso-> <propiedad name = "breakafteracquirefailure" value = "$ {db.breakafteracquireFailure}" /> <!-Para un consumo de alto rendimiento, solo úselo cuando sea necesario. Si se establece en True, su validez se verificará en cada envío de conexión. Se recomienda utilizar idleconnectionTestperiod o AutomatictStTable para mejorar el rendimiento de las pruebas de conexión. Predeterminado: falso-> <propiedad name = "testConnectionOncheckout" value = "$ {db.testConnectionOncheckout}"/> </ bean> <!-La diferencia entre mybatis configuration.classpath y classpath*, consulte el documento: http://blog.csdn.net/zl3450341/article/details Solo devolverá el primer recurso coincidente. Se recomienda usar classPath para un solo documento que determine la ruta; Use classpath*cuando coincida con múltiples documentos .--> <bean id = "sqlsessionFactory" p: dataSource-ref = "dataSource" p: configlocation = "classpath: mybatis.xml" p: mapperLocations = "classpath*: mapper /*mapper.xml" /> <!-banePackage las especificaciones de las especificaciones a las especificaciones a ser un paquete a ser y ser un paquete a ser y ser un mampú y el mampú y el mampú y el mampú MAPPEs y el paquete a ser un paquete y el paquete a ser y el paquete es Se buscará el paquete. Se pueden especificar múltiples paquetes. MappersCannerConfigurer escaneará todas las clases de interfaz (incluidos los subpackages) en el paquete especificado por BasePackage. Si se han definido en el archivo de mapeo SQL, se definirán dinámicamente como un frijol de resorte. -> <propiedad name = "basePackage" value = "com.everseeker.dao" /> <propiedad name = "sqlsessionFactoryBeanName" value = "sqlsessionFactory" /> </lebe> <!-Configuración del administrador de transacciones, utilizando las transacciones JDBC-> <bean> id = "TransactionManager" class = "org.springframework.jdbc.datasource.datasourcetransactionManager"> <propiedad name = "dataSource" ref = "dataSource" /> </ bean> <!- Use la anotación para definir transacciones y procesar granos de granos con @transactional anotación a los aspectos de la gestión de transacción. Por defecto, un administrador de transacciones llamado TransactionManager se usa automáticamente. Proxy-Target-Class es verdadero, lo que indica que Spring proxy las clases de negocios creando subclases y necesita agregar la biblioteca de clases cglib.jar al classpath. -> <tx: transacción-manager-manager de anotación = "transaccionManager" proxy-target-class = "true" /></beans>spring-mybatis.xml3. Cree la clase de usuario y la interfaz UserDAO.
Usuario de clase pública {@size (min = 32, max = 32, mensaje = "uuid debería ser una cadena de 32 bits") ID de cadena privada; @size (min = 1, max = 32, mensaje = "La longitud de la cuenta debe estar entre 1-32-bit") privado string username; @notempty (mensaje = "Mensaje" no puede estar vacío ") Cadena privada; @notempt (=" = "" Correo electrónico ") El formato es incorrecto ") Correo electrónico de cadena privada; @size (min = 11, max = 11, mensaje =" La longitud del número de teléfono móvil es 11 dígitos ") String de cadena privada de teléfono celular; RegDate Long Private; Public User () {this.id = uuid.randomuuid (). toString (). reemplazo ("-","); this.regdate = 0;} usuar correo electrónico, cadena celular) {this (nombre de usuario, contraseña, correo electrónico, teléfono celular, nueva fecha (). getTime ());} Usuario público (String UserName, String Password, String Correo electrónico, String Cell teléfono celular, Long RegDate) {this.id = uuid.randomuuid (). tostring (). correo electrónico; this.cellphone = celular celular; this.regDate = regDate;} public String getId () {return id;} public void setid (string id) {this.id = id;} public String getUsername () {return username;} public void setUsername (string username) {this.useName; setPassword (String Password) {this.password = contraseña;} public String getemail () {return Correo electrónico;} public void setEmail (string email) {this.email =} correaje;} public string getCellphone () {return Cell teléfono;} public void setcellphone (string cell teléfono) {this.cellphone = cellphone; pública pública long getreggregdate () {return setCellphone;} setRegDate (long regDate) {this.regDate = regDate;}@overRidePublic string toString () {return "[user: id =" + id + ", username =" + username + ", contraseña =" + contraseña + ", correo electrónico =" + correo electrónico + ", celular =" + celular + ", regDate =" regDate + "]";Comentarios como @notnull, @notempty, @size y @email en user.java se ignoran y explican temporalmente más tarde.
@RepositoryPublic Interface userDao {void adduser (usuario de usuario); user getUserByUserName (String UserName);}4. Cree el archivo de asignación usermapper.xml en el directorio SRC/Main/Resources/Mapper para implementar los métodos en la interfaz UserDAO. Nota: *El archivo mapper.xml debe colocarse en el directorio SRC/Main/Resources, y se colocó previamente en el directorio SRC/Main/Java/Com/Everseeker/DAO, lo que resultó en un error inexplicable.
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace = "com.everseeker.dao.userdao"> <resultmap id = "resultMapUser" type = "com.everseeker.entity.user"> </resultmap> <insertar id = "aduser" parameterType = "user"> en user (id, nombre de usuario, contraseña, correo electrónico, celular, regdo) valores ( #{{{{{ {it # #} #},},}, » #{contraseña}, #{correo electrónico}, #{celular}, #{regdate}) </sert> <select id = "getUserByUsername" parametertype = "string" resultMap = "resultMapuser"> select * de username = #{usernam Iii. COI
1. Cree un contenedor IOC y use el método de anotación para rootconfig.java.
@Configuration@componentScan (basepackages = {"com.everseeker"}, excludeFilters = {@componentScan.filter (type = filtreType.custom, value = rootconfig.webpackage.class)})@imporptorTresource ({"classpath: treing-mybatis.xml"}) public Class Class WebPackage extiende REGEXPATRINTTYPEFILTER {public WebPackage () {super (Pattern.Compile ("Com //. Everseeker //. Web"));}} @Configuration: indica que esta es una clase de configuración.
@ComponentsCan: Habilitar el escaneo de componentes, Basepackages: el paquete básico que debe escanear. ExcludeFilters: no escanee si el filtro cumple con las condiciones del filtro.
@ImpORTresource: introducir el archivo XML.
@PropertySource: introducir archivos de propiedades.
2. Dado que se crea el proyecto WebApp y se utiliza SpringMVC, el desplazamiento del servidor es el núcleo. En versiones de primavera anteriores, generalmente se configuró en Web.xml. En la primavera 4, se puede implementar en el código Java. WebAppinitializer.java.
Public Class WebAppinitializer extiende AbstractAnnotationConfigDispatcherservletInitializer {// La clase que hereda abstractAnnotationConfigDisPatcherservletInItializer configurará automáticamente el contexto de la aplicación desplazada y resorte @OverrideProtected String [] GetServletMappings () {// Map theatcherServlet to "/" Devuelve [] string [] []/"/"/};};};};}; RootConfig class is used to configure the beans in the application context created by ContextLoaderListener,* For example, @Repository, @Service and other components*/@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class<?>[] { RootConfig.class };}/*** When the DispatcherServlet loads the application context, use beans defined in the La clase de configuración de WebConfig, * se usa para cargar frijoles que contienen componentes web, como controladores, ver analizadores y asignaciones de procesadores, @Controller, @RequestMapping, etc.*/@overrideProtected Class <?> [] GetServletConfigClasses () {return New Class <?> [] {webConfig.class};} @overRideProtideProtideProideprotedExected customizeRegistration(ServletRegistration.Dynamic registration) {//Limit the uploaded file size to no more than 2MB, the entire request does not exceed 4M, and all uploaded files must be written to disk registration.setMultipartConfig(new MultipartConfigElement("/tmp/uploads", 2097152, 4194304, 0));}}3. Crear webconfig.java.
@Configuration@enablewebmvc@componentscan ("com.everseeker.web") public class webConfig extiende webMVCConfigurerAdapter {// Configurar JSP View Parser @BeanPublic ViewResolver ViewResolver () {InternerResourCeVewResolver RecurseViewViewResolver = new New InternalResourCeViewResolver (); ResourceViewResolver.SetPrefix ("/web-Inf/Views/"); ResourceViewResolver.SetSuffix (". JSP"); ResourceViewResolver.SetExPoseContextBeansAsAttributes (verdadero); ReturnCeViewVeWResolver;} // Configurar el múltiple @ MultipartResolver multipartResolver () lanza IOException {return New StandardServletMultIParTresOlver ();} // Configure el procesamiento de recursos estáticos @OverridePublic Void ConfiguradofaultServLethandling (defaultServLethandlerConfigurer Configurar) {configurador.enable ();}}}@Bean: declarar que este método crea una instancia del tipo deseado y se registra como un bean en el contexto de la aplicación de primavera.
Lo anterior es la explicación detallada de Spring Learning Note 1, COI, introducida por el editor, para usted, intente usar anotaciones y código Java tanto como sea posible. Espero que sea útil para todos. Si tiene alguna pregunta, déjame un mensaje y el editor responderá a todos a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!