ps: it's relatively simple. It's used to lay the foundation for us to use springboot
1: Objectives
- Integration: springmvc+spring+mybatis+maven
- Small function: query all user information
2: Integration ideas:
- pom dependency
- configuration file
- Run through a small function
3: Integration steps:
(1) New maven project
(2) pom dependency
- Spinning core package
- Springmvc
- Mybatis
- Mysql driver
- Druid
- Log related
- Test related
- Mybatis and spring integration
- Servlet-api,jsp-api,jstl
- Jackson-databind
<?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>club.info</groupId> <artifactId>ssm_anno</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>ssm_anno Maven Webapp</name> <properties> <spring.version>5.2.2.RELEASE</spring.version> </properties> <dependencies> <!-- serlvet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.0</version> <scope>provided</scope> </dependency> <!-- jsp --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <!--spring Relevant--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <!-- springmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- File upload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <!-- json Support --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <!-- mybatis Relevant --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> <!-- Connection pool --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> <!-- mysql drive --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- Journal logback --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.2.3</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> <!-- ellipsis get/set Method --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <target>1.8</target> <source>1.8</source> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <port>8888</port> <path>/</path> <uriEncoding>utf-8</uriEncoding> </configuration> </plugin> </plugins> </build> </project>
(3) Configuration class
1: web container
-
Core configuration of Web project, replacing web.xml
package club.info.ssm.config; import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.Filter; public class GolfingWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { /** * root Container configuration: load spring configuration * @return */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{ServiceConfig.class,TxConfig.class,DaoConfig.class}; } /** * servlet Container: loading spring MVC configuration * @return */ @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } /** * Mapping: configuring interception rules * @return */ @Override protected String[] getServletMappings() { return new String[]{"/"}; } /** * Filter: handle post garbled * @return */ @Override protected Filter[] getServletFilters() { CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter(); encodingFilter.setEncoding("utf-8"); return new Filter[]{encodingFilter}; } }
2: Interface layer configuration
-
In addition to scanning the controller, a series of functions should be configured (three major devices, custom format converter, interceptor, exception processor, file upload and download...)
package club.info.ssm.config; import club.info.ssm.utils.CustomIntercepter; import club.info.ssm.utils.DateConvertor; import club.info.ssm.utils.GlobalExceptionHandler; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.multipart.commons.CommonsMultipartResolver; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.view.InternalResourceViewResolver; import java.util.Date; import java.util.List; @Configuration @EnableWebMvc @ComponentScan("club.info.ssm.controller") public class SpringMvcConfig implements WebMvcConfigurer { /* view resolver */ @Bean public InternalResourceViewResolver viewResolver(){ InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); internalResourceViewResolver.setPrefix("/"); internalResourceViewResolver.setSuffix(".jsp"); return internalResourceViewResolver; } /* Format converter: see the following spring MVC configuration implementation for details */ @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new DateConvertor()); } /* Interceptor: see the following spring MVC configuration implementation for details */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new CustomIntercepter()).addPathPatterns("/**"); } /* Global exception handler: see the following spring MVC configuration implementation for details */ // @Override // public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) { // resolvers.add(new GlobalExceptionHandler()); // } @Bean public GlobalExceptionHandler globalExceptionHandler(){ return new GlobalExceptionHandler(); } /* File upload and download */ @Bean public CommonsMultipartResolver multipartResolver(){ return new CommonsMultipartResolver(){{ setMaxUploadSize(2000000L); setDefaultEncoding("utf-8"); }}; } }
3: Business logic layer configuration
-
This is simple. Just scan the service package
package club.info.ssm.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("club.info.ssm.service") public class ServiceConfig { }
4: Persistence layer configuration
-
Here, we need to integrate mybatis and import external resource files
package club.info.ssm.config; import com.alibaba.druid.pool.DruidDataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import javax.sql.DataSource; /** * All rights Reserved, Designed By www.info4z.club * <p>title:club.info.ssm.config</p> * <p>ClassName:DaoConfig</p> * <p>Description:TODO(Please describe the function of this class in one sentence.)</p> * <p>Compony:Info4z</p> * author:poker_heart * date:2019/12/18 * version:1.0 * Note: this content is limited to internal circulation of the company, and is prohibited to be disclosed and used for other commercial purposes */ @Configuration @PropertySource("classpath:application.properties") public class DaoConfig { /** * Configure the Druid connection pool. Note that if the incoming parameter must be a spring managed object * @param env * @return */ @Bean public DataSource dataSource(Environment env){ DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(env.getProperty("druid.driverClass")); dataSource.setUrl(env.getProperty("druid.url")); dataSource.setUsername(env.getProperty("druid.username")); dataSource.setPassword(env.getProperty("druid.password")); return dataSource; } @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){ SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setTypeAliasesPackage("club.info.ssm.pojo"); return sqlSessionFactoryBean; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setBasePackage("club.info.ssm.dao"); return configurer; } }
5: Declarative transaction
-
This is simple. Just turn on annotation drive
package com.ujiuye.ssm.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; @Configuration @EnableTransactionManagement public class TxConfig { @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); return dataSourceTransactionManager; } }
(4) Spring MVC configuration implementation
1: Format converter
-
Just implement the converter interface
package com.ujiuye.ssm.utils; import org.springframework.core.convert.converter.Converter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DateConvertor implements Converter<String, Date> { @Override public Date convert(String source) { try { return new SimpleDateFormat("yyyy-MM-dd").parse(source); } catch (ParseException e) { e.printStackTrace(); } return null; } }
2: Interceptor
-
custom interceptor
package com.ujiuye.ssm.utils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CustomIntercepter implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("pre"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("post"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("completion"); } }
3: Global exception handler
-
Implement HandlerExceptionResolver interface
package com.ujiuye.ssm.utils; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.io.StringWriter; public class GlobalExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { StringWriter writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); String message = ex.getMessage(); String msg = writer.toString(); System.out.println("message: "+message); System.out.println("msg: "+msg); ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("msg",msg); return modelAndView; } }
(5) mybatis configuration
- Core configuration files are omitted through mybatis spring
- The mapping configuration can be xml or annotation. The annotation is readable and the configuration file is more flexible
(6) Profile
1: External resource file
-
db.properties
druid.driverClass=com.mysql.jdbc.Driver druid.url=jdbc:mysql://localhost:3306/test_z druid.username=root druid.password=root
2: Log configuration
-
logback.xml
<?xml version="1.0" encoding="UTF-8" ?> <configuration xmlns="http://ch.qos.logback/xml/ns/logback" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ch.qos.logback/xml/ns/logback https://raw.githubusercontent.com/enricopulatzo/logback-XSD/master/src/main/xsd/logback.xsd"> <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>error</level> <onMatch>DENY</onMatch> <onMismatch>ACCEPT</onMismatch> </filter> <encoder> <pattern>%msg%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>D:/temp/info.%d.log</fileNamePattern> </rollingPolicy> </appender> <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>error</level> </filter> <encoder> <pattern>%msg%n</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>D:/temp/error.%d.log</fileNamePattern> </rollingPolicy> </appender> <root level="info"> <appender-ref ref="consoleLog" /> <appender-ref ref="fileInfoLog" /> <appender-ref ref="fileErrorLog" /> </root> </configuration>
(7) Implementation function
1: Pojo
-
person.java
package club.info.ssm.pojo; import lombok.Data; import java.util.Date; @Data public class Person { private Integer id; private String name; private Integer sex; private Date birthday; }
2: Dao
-
PersonDao.java
package club.info.ssm.dao; import club.info.ssm.pojo.Person; import java.util.List; public interface PersonDao { @Select("select * from person") List<Person> findAll(); }
3: Service
-
PersonServiceImpl.java
package club.info.ssm.service.impl; import club.info.ssm.dao.PersonDao; import club.info.ssm.pojo.Person; import club.info.ssm.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional public class PersonServiceImpl implements PersonService { @Autowired private PersonDao personDao; @Override public List<Person> findAll() { return personDao.findAll(); } }
4: controller
-
PersonController.java
package club.info.ssm.controller; import club.info.ssm.pojo.Person; import club.info.ssm.service.PersonService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class PersonController { @Autowired private PersonService personService; @Autowired Environment env; @GetMapping("findAll") public List<Person> findAll(){ System.out.println(env.getProperty("jdbc.driverClass")); return personService.findAll(); } @PostMapping("save") public void save(Person person){ System.out.println(person); } }