Learning Spring in practice, the ultimate goal of this series is to complete a project that implements the user registration and login function.
The expected basic process is as follows:
1. Register the user website, fill in the user name, password, email, and mobile phone number information, and return ok after depositing it in the database in the background. (Learn the basic knowledge of IOC, mybatis, SpringMVC, form data verification, file upload, etc.)
2. The server sends emails asynchronously to the registered user. (Learn message queue)
3. User login. (Learning Cache, Spring Security)
4. Others.
Study and summarize, and update from time to time. The project environment is Intellij + Spring4.
1. Preparation work.
1. Create database and tables in mysql.
2. Create a maven webapp project in Intellij.
(1) Import the required dependency packages in pom.xml.
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.everSeeker</groupId><artifactId>register</artifactId><packaging>war</packaging><version>1.0</version><name>register Maven Webapp</name><url>http://maven.apache.org</url><properties><spring.version>4.3.1.RELEASE</spring.version></properties><dependencies><!--spring core, context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifa ctId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</ve rsion></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><!--test--><dependency><groupId>junit</groupId><ar tifactId>junit</artifactId><version>4.12</version><!--<scope>test</scope>--></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</ve rsion></dependency><!--springmvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springfr amework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>1.1.0.Fin al</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.2.4.Final</version></dependency><!--servlet--><dependency><groupId>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><!--mysql, mybatis--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifact</artifact Id><version>6.0.3</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</art ifactId><version>1.3.0</version></dependency><dependency><groupId>c3p0</groupId><artifactId>c3p0</artifactId><version>0.9.1.2</version></dependency></dependencies><build><finalName>java_config_web</finalName><plugins><plugi n><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.2</version><configuration><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin></plugins></build></project> (2) The project directory structure is as follows:
2. Mybatis
1. Configure the basic information of mysql database.
# Databasedb.mysql.driverClass = com.mysql.jdbc.Driverdb.mysql.jdbcUrl = jdbc:mysql://localhost:3306/register_Notice?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=truedb.mysql.user = rootdb.mysql.password = 333db.minPoolSize = 10db.maxPoolSize = 100db.initialPoolSize = 20db.maxIdleTime = 60db.acquireIncrement = 5db.maxStatements = 100db.idleConnectionTestPeriod = 60db.acquireRetryAttempts = 30db.breakAfterAcquireFailure = truedb.testConnectionOnCheckout = falsedb.properties
2. Configure mybatis.xml and spring-mybatis.xml.
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!--Configuration entity class alias--><typeAliases><!-- Choose one of the following two methods. Method 1: Use typeAlias to set aliases for a single class. --><!--<typeAlias type="com.everSeeker.entity.User" alias="User" />--- Method 2: Use package to set aliases for all classes below the package. The default rule is com.everSeeker.entity.User is set to User, and remove the previous package name. --><package name="com.everSeeker.entity" /></typeAliases></configuration>mybatis.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.sp ringframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- Introducing the db.properties file into this file can ensure that the corresponding value can be found in the subsequent configuration such as ${db.mysql.driverClass}-- Otherwise, if a colleague directly loads db.properties and spring-mybatis.xml in RootConfig.java, it cannot be guaranteed that db.properties will be introduced first, resulting in a program error--><context:property-placeholder location="classpath:db.properties"/><!--Data source configuration c3p0 has 2 common data source implementation class packages, one is apache DBCP (org.apache.commons.dbcp.BasicDataSource), and the other is C3P0. --><bean id="dataSource"destroy-method="close"><property name="driverClass" value="${db.mysql.driverClass}" /><property name="jdbcUrl" value="${db.mysql.jdbcUrl}" /><property name="user" value="${db.mysql.user}" /><property name="password" value="${db.mysql.password}" /><!--The minimum number of connections retained in the connection pool. --><property name="minPoolSize" value="${db.minPoolSize}" /><!--The maximum number of connections retained in the connection pool. Default: 15 --><property name="maxPoolSize" value="${db.maxPoolSize}" /><!--The number of connections obtained during initialization should be between minPoolSize and maxPoolSize. Default: 3 --><property name="initialPoolSize" value="${db.initialPoolSize}" /><!--Maximum free time, if not used within 60 seconds, the connection will be discarded. If it is 0, it will never be discarded. Default: 0 --><property name="maxIdleTime" value="${db.maxIdleTime}" /><!--The number of connections obtained by c3p0 at the same time at one time when the connection in the connection pool is exhausted. Default: 3 --><property name="acquireIncrement" value="${db.acquireIncrement}" /><!--JDBC's standard parameters are used to control the number of PreparedStatements loaded in the data source. But because precache statements belong to a single connection rather than the entire connection pool. Therefore, setting this parameter requires considering many factors. If both maxStatements and maxStatementsPerConnection are 0, the cache is closed. Default: 0 --><property name="maxStatements" value="${db.maxStatements}" /><!- Check all connections in the connection pool every 60 seconds. Default: 0 --><property name="idleConnectionTestPeriod" value="${db.idleConnectionTestPeriod}" /><!-Defines the number of repeated attempts after a new connection failed to be retrieved from the database. Default: 30 --><property name="acquireRetryAttempts" value="${db.acquireRetryAttempts}" /><!--Acquiring a connection will cause all threads waiting for the connection pool to get the connection to throw an exception. However, the data source is still valid and continues to try to get the connection the next time you call getConnection(). If set to true, the data source will declare that it has been disconnected and permanently closed after failed attempts to obtain the connection. Default: false --><property name="breakAfterAcquireFailure" value="${db.breakAfterAcquireFailure}" /><!--For high performance consumption, please only use it when needed. If set to true, its validity will be verified at each connection submission. It is recommended to use idleConnectionTestPeriod or automaticTestTable to improve the performance of connection testing. Default: false --><property name="testConnectionOnCheckout" value="${db.testConnectionOnCheckout}" /></bean><!-- The difference between myBatis configuration.classpath and classpath*, refer to the document: http://blog.csdn.net/zl3450341/article/details/9306983.classpath will only return the first matching resource. It is recommended to use classpath for a single document that determines the path; use classpath* when matching multiple documents.--><bean id="sqlSessionFactory"p:dataSource-ref="dataSource"p:configLocation="classpath:mybatis.xml"p:mapperLocations="classpath*:mapper/*Mapper.xml" /><bean><!--basePackage specifies the package to be scanned, and the mappers under this package will be searched. Multiple packages can be specified. The MapperScannerConfigurer will scan all interface classes (including subpackages) under the package specified by basePackage. If they have been defined in the SQL mapping file, they will be dynamically defined as a Spring Bean. --><property name="basePackage" value="com.everSeeker.dao" /><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /></bean><!-- Transaction Manager Configuration, Using jdbc transactions--><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource" /></bean><!-- Use annotation to define transactions and process beans marked with @Transactional annotation to weave transaction management aspects. By default, a transaction manager named transactionManager is automatically used. proxy-target-class is true, indicating that spring will proxy business classes by creating subclasses, and needs to add the CGLib.jar class library to the classpath. --><tx:annotation-driven transaction-manager="transactionManager"proxy-target-class="true" /></beans>spring-mybatis.xml3. Create User class and UserDao interface.
public class User {@Size(min = 32, max = 32, message = "uuid should be a 32-bit string") private String id;@Size(min = 1, max = 32, message = "The account length should be between 1-32 bits") private String username;@NotEmpty(message = "Password cannot be empty") private String password;@NotEmpty(message = "email cannot be empty")@Email(message = "email format is incorrect") private String email;@Size(min = 11, max = 11, message = "The length of the mobile phone number is 11 digits")private String cellphone;private long regDate;public User() {this.id = UUID.randomUUID().toString().replaceAll("-", "");this.regDate = 0;}public User(String username, String password, String email, String cellphone) {this(username, password, email, cellphone, new Date().getTime());}public User(String username, String password, String email, String cellphone, long regDate) {this.id = UUID.randomUUID().toString().replaceAll("-", "");this.username = username;this.password = password;this.email = email;this.cellphone = cellphone;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.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getCellphone() {return cellphone;}public void setCellphone(String cellphone) {this.cellphone = cellphone;}public long getRegDate() {return regDate;}public void setRegDate(long regDate) {this.regDate = regDate;}@Overridepublic String toString() {return "[User: id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", cellphone=" + cellphone + ", regDate=" + regDate + "]";}}User.javaComments such as @NotNull, @NotEmpty, @Size and @Email in User.java are temporarily ignored and explained later.
@Repositorypublic interface UserDao {void addUser(User user);User getUserByUsername(String username);}4. Create the UserMapper.xml mapping file in the src/main/resources/mapper directory to implement the methods in the UserDao interface. Note: *Mapper.xml file must be placed in the src/main/resources directory, and was previously placed in the src/main/java/com/everSeeker/dao directory, resulting in an inexplicable error.
<?xml version="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><insert id="addUser" parameterType="User">INSERT INTO user(id, username, password, email, cellphone, regDate) VALUES(#{id}, #{username}, #{password}, #{email}, #{cellphone}, #{regDate})</insert><select id="getUserByUsername" parameterType="String" resultMap="ResultMapUser">SELECT * FROM user WHERE username=#{username}</select></mapper>UserMapper.xml III. IOC
1. Create an IOC container, and use annotation method to RootConfig.java.
@Configuration@ComponentScan(basePackages = {"com.everSeeker"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, value = RootConfig.WebPackage.class)})@ImportResource({"classpath:spring-mybatis.xml"})public class RootConfig {public static class WebPackage extends RegexPatternTypeFilter {public WebPackage() {super(Pattern.compile("com//.everSeeker//.web"));}}} @Configuration: Indicates that this is a configuration class.
@ComponentScan: Enable component scanning, basePackages: The basic package that needs to be scanned. excludeFilters: Do not scan if the filter meets the filter conditions.
@ImportResource: Introduce xml file.
@PropertySource: Introduce properties files.
2. Since the webapp project is created and SpringMVC is used, the DispatcherServlet is the core. In previous Spring versions, it was generally configured in web.xml. In Spring 4, it can be implemented in Java code. WebAppInitializer.java.
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //The class inheriting AbstractAnnotationConfigDispatcherServletInitializer will automatically configure the DispatcherServlet and Spring application context @Overrideprotected String[] getServletMappings() { //Mapping the DispatcherServlet to "/"return new String[] { "/" };}/*** The 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 WebConfig configuration class, * is used to load beans containing Web components, such as controllers, view parsers and processor mappings, @Controller, @RequestMapping, etc.*/@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class<?>[] { WebConfig.class };}@Overrideprotected void 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. Create WebConfig.java.
@Configuration@EnableWebMvc@ComponentScan("com.everSeeker.web")public class WebConfig extends WebMvcConfigurerAdapter {//Configure jsp view parser @Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver();resourceViewResolver.setPrefix("/WEB-INF/views/");resourceViewResolver.setSuffix(".jsp");resourceViewResolver.setExposeContextBeansAsAttributes(true);return resourceViewResolver;}//Configure the multipart parser and use @Beanpublic MultipartResolver multipartResolver() throws IOException {return new StandardServletMultipartResolver();}//Configure static resources processing @Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configure) {configurer.enable();}}@Bean: Declaring this method creates an instance of the desired type and registers as a bean in the Spring application context.
The above is the detailed explanation of Spring Learning Note 1, IOC, introduced by the editor, to you, try to use annotations and java code as much as possible. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!