Integration of ssm based on annotation

Posted by dbradbury on Thu, 23 Apr 2020 12:14:24 +0200

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:

  1. pom dependency
  2. configuration file
  3. Run through a small function

3: Integration steps:

(1) New maven project

(2) pom dependency

  1. Spinning core package
  2. Springmvc
  3. Mybatis
  4. Mysql driver
  5. Druid
  6. Log related
  7. Test related
  8. Mybatis and spring integration
  9. Servlet-api,jsp-api,jstl
  10. 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);
        }
    }
    

Topics: Programming Spring Java Mybatis Druid