Learning Spring in combat, the ultimate goal of this series is to complete a project that enables users to sign in to the login feature.
The basic process envisioned is as follows:
1, the user website registration, fills in the user name, the password, the email, the mobile phone number information, backstage deposits the database to return OK. (Learn the basics of IOC,MYBATIS,SPRINGMVC, form data validation, file upload, etc.)
2, the server asynchronously send mail to registered users. (Learning Message Queuing)
3, User login. (Learning caching, Spring security)
4, other.
While learning side summary, not regularly updated. The project environment is IntelliJ + SPRING4.
First, the preparatory work.
1, MySQL build the database table.
2. Create Maven WebApp project in IntelliJ.
(1) Import the required dependency pack 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> <artifactid>spriNg-context-support</artifactid> <version>${spring.version}</version> </dependency> < Dependency> <groupId>org.springframework</groupId> <artifactid>spring-core</artifactid > <version>${spring.version}</version> </dependency> <dependency> <groupId> Org.springframework</groupid> <artifactId>spring-beans</artifactId> <version>${ Spring.version}</version> </dependency> <!--test--> <dependency> <groupid>junit</ Groupid> <artifactId>junit</artifactId> <version>4.12</version> <!--<scope> test</scope>--> </dependency> <dependency> <groupid>org.springframework</groupid > <artifactId>spring-test</artifactId> <version>${spring.version}</version> </ dependency> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> < Artifactid>spring-webmvc</artifactid> <version>${spring.version}</version> </dependency> < Dependency> <groupId>org.springframework</groupId> <artifactid>spring-web</artifactid > <version>${spring.version}</version> </dependency> <dependency> <groupId> Javax.validation</groupid> <artifactId>validation-api</artifactId> <version>1.1.0.final </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< /artifactid> <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</artifactid> <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> <pLugin> <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 structure of the engineering directory is as follows:
Second, MyBatis
1, configure the MySQL database basic information.
# Database
db.mysql.driverClass = com.mysql.jdbc.Driver
db.mysql.jdbcUrl = jdbc:mysql://localhost:3306/ Register_notice?useunicode=true&characterencoding=utf-8&allowmultiqueries=true
Db.mysql.user = root
Db.mysql.password = 333
db.minpoolsize =
db.maxpoolsize =
db.initialpoolsize
= Db.maxidletime =
db.acquireincrement = 5
db.maxstatements =
Db.idleconnectiontestperiod = 60
db.acquireretryattempts =
Db.breakafteracquirefailure = True
Db.testconnectiononcheckout = False
db.properties
2, configure Mybatis.xml and Spring-mybatis.xml.
<?xml version= "1.0" encoding= "UTF-8"?> <!
DOCTYPE configuration Public "-//mybatis.org//dtd Config 3.0//en" "Http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <!--Configure an alias for an entity class--> <typeAliases> <!--The following 2 ways to choose one. Method 1th: Use Typealias to set an alias for a single class. --> <!--<typealias type= "Com.everSeeker.entity.User" alias= "User"/>--> <!--2nd way: Using Package, The alias is set for all classes below the package, and the default rule is to set the Com.everSeeker.entity.User to user, removing 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" 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.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-bEans.xsd Http://www.springframework.org/schema/context http://www.springframework.org/schema/context/ Spring-context.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/ Spring-tx.xsd "> <!--introduce db.properties files in this file to ensure that subsequent configuration such as ${db.mysql.driverclass} can definitely find the corresponding value--> <!--otherwise, If the colleagues in the Rootconfig.java directly in the Db.properties and spring-mybatis.xml, can not guarantee that Db.properties was introduced first, resulting in a program error--> <context: Property-placeholder location= "Classpath:db.properties"/> <!--data source configuration c3p0 Common data source implementation class pack has 2, one is Apache DBCP (
Org.apache.commons.dbcp.BasicDataSource), the other is c3p0. --> <bean id= "DataSource" class= "Com.mchange.v2.c3p0.ComboPooledDataSource" 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 reserved 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 when initializing. The value should be between Minpoolsize and Maxpoolsize. Default:3--> <property name= "initialpoolsize" value= "${db.initialpoolsize}"/> <!--maximum idle time, not used within 60 seconds, the connection is discarded. If 0, it will never be discarded. default:0--> <property name= "MaxIdleTime" value= "${db.maxidletime}"/> <!--the number of connections that were fetched at one time when the connection in the connection pool was depleted. Default:3--> <property name= "acquireincrement" value= "${db.acquireincrement}"/> <!--JDBC Standard parameters, Used to control the number of preparedstatements loaded in the data source. However, because the cached statements belong to a single connection instead of the entire connection pool.
So setting this parameter takes into account many factors. If both maxstatements and maxstatementsperconnection are 0, the cache is closed. default:0--> <property name= "maxstatements" value= "${db.maxstatements}"/> <!--check for free connections in all connection pools every 60 seconds. default:0--> <property name= "Idleconnectiontestperiod" value= "${db.idleconnectiontestperiod}"/> <!-- Defines the number of repeated attempts after a new connection has failed to get from the database. default:30--> <property name= "Acquireretryattempts" ValUe= "${db.acquireretryattempts}"/> <!--getting a connection failure will cause all threads waiting to connect to get the connection to throw an exception. However, the data source remains valid and continues to attempt to get the connection the next time you call Getconnection (). If set to True, the data source will be declared disconnected and permanently closed after the attempt to acquire the connection fails. Default:false--> <property name= "breakafteracquirefailure" value= "${db.breakafteracquirefailure}"/> Because of the high performance, please use it only when you need it. If set to true then the validity is officers transferred Guevara for each connection submission. It is recommended that you use methods such as Idleconnectiontestperiod or automatictesttable to improve the performance of your connection tests. Default:false--> <property name= "testconnectiononcheckout" value= "${db.testconnectiononcheckout}"/>
bean> <!--mybatis configuration.
The difference between classpath and classpath*, reference documentation: http://blog.csdn.net/zl3450341/article/details/9306983.
Classpath only returns the first matching resource, it is recommended that a single document that determines the path use Classpath, and classpath* is used when matching multiple documents. --> <bean id= "sqlsessionfactory class=" Org.mybatis.spring.SqlSessionFactoryBean "p:datasource-ref=" DataSource "p:configlocation=" Classpath:mybatis.xml "p:mapperlocations=" Classpath*:mapper/*mapper.xml "/> < Bean class= "Org.mybatis.spring.mapper.MapperScannerConfigurer" > <!--basepackage Specifies that you want to scanPackage, the mapper under this package will be searched. Multiple packages can be specified, separated by commas or semicolons, Mapperscannerconfigurer scans all interface classes (including child packages) under the Basepackage specified package, and if they are defined in the SQL mapping file, they are dynamically defined as a spring Bean. --> <property name= "basepackage" value= "Com.everSeeker.dao"/> <property "name=" Sqlsessionfactorybeanname "Value=" sqlsessionfactory/> </bean> <!--transaction manager configuration, using JDBC transaction--> <bean id= "TransactionManager" class= "Org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name= "DataSource" ref= "
The DataSource "/> </bean> <!--uses annotation to define transactions to process the bean that has the @transactional annotation annotated to weave into the Transaction Management section.
By default, the transaction manager with the name TransactionManager is automatically used. Proxy-target-class is true to indicate that spring will proxy the business class by creating subclasses, and that a Cglib.jar class library needs to be added to the classpath. --> <tx:annotation-driven transaction-manager= "TransactionManager" proxy-target-class= "true"/> </beans > Spring-mybatis.xml
3, create the user class, and the Userdao interface.
public class User {@Size (min =, max = n, message = "UUID should be 32-bit string") private String ID; @Size (min = 1, max = mess
Age = "Account length should be between 1-32 digits") private String username;
@NotEmpty (message = "Password cannot be null") private String password;
@NotEmpty (message = "Email cannot be empty") @Email (message = "Incorrect email format") Private String Email;
@Size (min = one, max = one, message = "Cell phone number length 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 e-mail, string cellphone) {This (username, password, email, cellphon
E, 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;} p Ublic string Getemail () {return e-mail;} public void Setemail (String email) {this.email = email;} public string Getcell Phone () {return cellphone.} public void Setcellphone (String cellphone) {this.cellphone = cellphone;} public long Getre Gdate () {return regdate.} public void Setregdate (long regdate) {this.regdate = regdate;} @Override public String tostr ing () {return "[user:id=" + ID + ", username=" + Username + ", password=" + password + ", email=" + email + ", cellphone
= "+ Cellphone +", regdate= "+ RegDate +"]; }} User.java
@notnull, @NotEmpty, @Size, and @email in User.java are temporarily ignored and later explained.
@Repository Public
interface Userdao {
void AddUser (user user);
User Getuserbyusername (String username);
4, in the Src/main/resources/mapper directory to create usermapper.xml mapping file, the implementation of the Userdao interface methods. Note: *mapper.xml files must be placed in the Src/main/resources directory, before placed in the Src/main/java/com/everseeker/dao directory, resulting in inexplicable wonderful mistakes.
<?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" Com.everSeeker.entity.User ">
</resultMap>
<insert id=" AddUser "parametertype=" User ">
INSERT into user (ID, username, password, email, cellphone, regdate) VALUES (#{id}, #{username}, #{password}, #{email}, #{ce Llphone}, #{regdate})
</insert>
<select id= "Getuserbyusername" String "parametertype=" Resultmapuser ">
SELECT * from user WHERE username=#{username}
</select>
</mapper>
Usermapper.xml
Third, the IOC
1, the creation of the IOC container, by way of annotation, 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 the build scan, Basepackages: the underlying package that needs to be scanned. Excludefilters: does not scan according to filter condition.
@ImportResource: Introducing an XML file.
@PropertySource: The properties file is introduced.
2, because the creation is the WebApp project, and uses the SPRINGMVC, then Dispatcherservlet is the core. In previous spring versions, they are typically configured in Web.xml. In Spring4, it can be implemented in Java code. Webappinitializer.java.
public class Webappinitializer extends Abstractannotationconfigdispatcherservletinitializer {// Classes that inherit Abstractannotationconfigdispatcherservletinitializer automatically configure the Dispatcherservlet and Spring application contexts @Override protected String[] Getservletmappings () {//Dispatcherservlet map to '/' return new string[] {'/'};}/** * RootConfig class is used to configure Contextload
Erlistener created in the application context of the bean, * such as @repository, @Service and other components * * * @Override protected class<?>[] Getrootconfigclasses () {
return new class<?>[] {rootconfig.class}; /** * Dispatcherservlet When loading the application context, use the bean defined in the Webconfig configuration class, * to load the bean containing the Web component, such as the controller, the view parser, and the processor map, @Controller, @ requestmapping etc/@Override protected class<?>[] Getservletconfigclasses () {return new class<?>[] {webconf
Ig.class}; @Override protected void Customizeregistration (Servletregistration.dynamic registration) {//Limit the size of the uploaded file to no more than 2MB, The entire request does not exceed 4M, all uploaded files are written to the 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 {
//config JSP view parser
@Bean public
viewresolver viewresolver () {
Internalresourceviewresolver resourceviewresolver = new Internalresourceviewresolver ();
Resourceviewresolver.setprefix ("/web-inf/views/");
Resourceviewresolver.setsuffix (". jsp");
Resourceviewresolver.setexposecontextbeansasattributes (true);
return resourceviewresolver;
}
Configure the multipart parser to upload files with
@Bean public
multipartresolver Multipartresolver () throws IOException {
return new Standardservletmultipartresolver ();
}
Configure the processing of static resources
@Override public
void Configuredefaultservlethandling (defaultservlethandlerconfigurer Configurer) {
configurer.enable ();
}
}
@Bean: Declaring this method creates an instance of the desired type and registers it as a Bean in the spring application context.
The above is a small set to introduce the spring Learning Notes 1 of the IOC detailed use of annotations as well as Java code, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!