springboot+mybatis学习

springboot+mybatis学习

概述

springboot+mybatis+druid+swagger2学习

环境

  • springboot 2.1.3
  • mybatis 1.3.0
  • druid 1.1.0
  • swagger2 2.2.2

代码结构

在这里插入图片描述

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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <docker.image.prefix>springboot</docker.image.prefix>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.2.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <jvmArguments>
                        -Xdebug
                        -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
                    </jvmArguments>
                </configuration>
            </plugin>
            <!-- Docker maven plugin -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
            <!-- Docker maven plugin -->
        </plugins>
    </build>

</project>

application.yml

server:
  port: 80
#配置数据源
spring: 
  datasource:
     url: jdbc:mysql://192.168.0.69:12345/wechat?useUnicode=true&characterEncoding=utf8
     username: root
     password: ******
     type: com.alibaba.druid.pool.DruidDataSource
     druid:
      # 下面为连接池的补充设置,应用到上面所有数据源中
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      pool-prepared-statements: true
      #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat,wall
      use-global-data-source-stat: true
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      # 配置监控服务器
      stat-view-servlet:
        login-username: admin
        login-password: 123456
        reset-enable: false
        url-pattern: /druid/*
        # 添加IP白名单
        allow: 192.168.0.8
        # 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
        #deny:
      web-stat-filter:
        # 添加过滤规则
        url-pattern: /*
        # 忽略过滤格式
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
        
  #热部署生效
  devtools:
    restart:
     enabled: false
     #设置重启的目录
     additional-paths: src/main/java
     #classpath目录下的WEB-INF文件夹内容修改不重启
     exclude: WEB-INF/**

#指定mybatis映射文件的地址
mybatis:
  mapper-locations: classpath:mapper/*.xml

swagger:
  show: true

DemoApplication.java

package com.example.demo;

import javax.sql.DataSource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.annotation.Bean;

import com.alibaba.druid.pool.DruidDataSource;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication
@ServletComponentScan
@EnableSwagger2
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean(destroyMethod = "close", initMethod = "init")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
        return new DruidDataSource();
    }
}

BaseController.java

package com.example.demo.controller;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;

import org.apache.log4j.Logger;

public class BaseController<T extends Serializable> {
    protected Logger logger;
    protected SimpleDateFormat dateFormat;

    @SuppressWarnings({ "rawtypes" })
    protected BaseController() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        logger = Logger.getLogger((Class) params[0]);
        dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
}

HelloWorldController.java

package com.example.demo.controller;

import java.io.Serializable;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.utils.DataFormatUtils;
import com.example.demo.utils.DemoConstants;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@Api("测试")
@RestController
public class HelloWorldController extends BaseController<AuthManagerController> implements Serializable {

    private static final long serialVersionUID = 1L;
    
    @Autowired
    private UserService userService;

    @ApiOperation("获取用户")
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public Map<String, Object> getUser() {
        User user = new User();
        String message = "";
        try {
            user = userService.selectUser(1);
        } catch (Exception e) {
            message = DemoConstants.GET_USER_ERROR;
            e.printStackTrace();
        }
        return DataFormatUtils.format(message, user);
    }

    @ApiIgnore
    @RequestMapping(value = "/save", method = RequestMethod.GET)
    public Map<String, Object> saveUser() {
        User user = new User();
        user.setId(2);
        user.setUserName("user2");
        user.setPassword("111");
        user.setTokenStartTime(12321423);
        String message = "";
        try {
            userService.saveUser(user);
        } catch (Exception e) {
            message = "error";
            e.printStackTrace();
        }
        return DataFormatUtils.format(message, user);
    }
}

UserService.java

package com.example.demo.service;

import com.example.demo.entity.User;

public interface UserService {

    public User selectUser(int id);

    public void saveUser(User user);
}

UserServiceImpl.java

package com.example.demo.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.dao.UserDao;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    public User selectUser(int id){
        return userDao.findUserById(id);
    }

    public void saveUser(User user) {
        userDao.saveUser(user);
    }

}

UserDao.java

package com.example.demo.dao;

import org.apache.ibatis.annotations.Mapper;

import com.example.demo.entity.User;

@Mapper
public interface UserDao {
    User findUserById(int id);
    User findUserByName(String userName);
    void saveUser(User user);
}

User.java

package com.example.demo.entity;

import java.io.Serializable;

import org.apache.commons.lang3.builder.ToStringBuilder;

public class User implements Serializable {
    
    private static final long serialVersionUID = 1L;

    private int id;
    private String userName;
    private String password;
    private long tokenStartTime;

    public int getId() {
        return id;
    }
    public void setId(int 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 long getTokenStartTime() {
        return tokenStartTime;
    }
    public void setTokenStartTime(long tokenStartTime) {
        this.tokenStartTime = tokenStartTime;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }
}


User.xml

<?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.example.demo.dao.UserDao">
    <select id="findUserById" parameterType="int"
        resultType="com.example.demo.entity.User">
        select * from user where id = #{id}
    </select>
    <select id="findUserByName" parameterType="String"
        resultType="com.example.demo.entity.User">
        select * from user where userName = #{userName}
    </select>
    <insert id="saveUser" parameterType="com.example.demo.entity.User">
        insert into user (id, username, password, tokenStartTime)
        values
        (#{id}, #{userName},
        #{password},
        #{tokenStartTime})
    </insert>
</mapper>

使用ResponseBodyAdvice指定response返回格式
DemoResponseBodyAdvice.java

package com.example.demo.advice;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.example.demo.utils.DemoConstants;
import com.example.demo.utils.UrlDataUtil;

@ControllerAdvice
public class DemoResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object responseBody, MethodParameter returnType,
            MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
            ServerHttpRequest request, ServerHttpResponse response) {
        URI uri = request.getURI();
        String path = uri.getPath();
        List<String> urlList = UrlDataUtil.getData();
        for (String urlName : urlList) {
            if (path.indexOf(urlName) != -1) {
                return responseBody;
            }
        }

        List<String> tokenList = response.getHeaders().get(DemoConstants.HTTP_HEADER_AUTHORIZATION);
        String token = "";
        if (! (tokenList == null || tokenList.isEmpty())) {
            token = tokenList.get(0);
        }
        Map<String, Object> responseMap = new HashMap<String, Object>();
        responseMap.put("data", response);
        responseMap.put(DemoConstants.TOKEN_NAME, token);
        return responseMap;
    }
}

使用HandlerInterceptorAdapter过滤器 进行token验证
AuthInterceptor.java

package com.example.demo.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.exception.DemoException;
import com.example.demo.service.AuthManagerService;
import com.example.demo.utils.DataFormatUtils;
import com.example.demo.utils.DemoConstants;
import com.example.demo.utils.StringUtil;
import com.example.demo.utils.UrlDataUtil;

public class AuthInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private AuthManagerService authManagerService;

    private Logger logger = Logger.getLogger(AuthInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

        boolean valid = true;
        String token = "";
        String newToken = "";
        Map<String, Object> data = new HashMap<String, Object>();

        String path = request.getRequestURI();
        List<String> urlList = UrlDataUtil.getData();
        for (String url : urlList) {
            if (!url.equals("/login")) {
                if (path.indexOf(url) != -1) {
                    token = request.getParameter(DemoConstants.HTTP_HEADER_AUTHORIZATION);
                    break;
                }
            }
        }
        if(token == null || token.equals("")) {
            token = request.getHeader(DemoConstants.HTTP_HEADER_AUTHORIZATION);
        }
        if (StringUtil.isNullOrEmpty(token)) {
            data = DataFormatUtils.tokenFormat(DemoConstants.AUTH_NO_TOKEN_MSG);
            valid = false;
        }
        
        if (valid) {
            try {
                newToken = authManagerService.refreshToken(token);
            } catch (Exception e) {
                data = DataFormatUtils.tokenFormat(e.getMessage());
                valid = false;
            }
        }

        if (valid) {
            response.setHeader(DemoConstants.HTTP_HEADER_AUTHORIZATION, newToken);
            return true;
        } else {
            String message = JSONObject.toJSONString(data);
            response.setCharacterEncoding(DemoConstants.DEFAULT_CHARSET);
            response.setContentType(DemoConstants.JSON_CHARSET);

            PrintWriter out = null;
            try {
                out = response.getWriter();
                out.append(message);
                out.flush();
            } catch (IOException e) {
                logger.error(StringUtil.formatErrorLogger(e, "preHandle"));
                new DemoException(e);
            } finally {
                if (out != null) {
                    out.close();
                }
            }
            return false;
        }
    }
}

InterceptorConfig.java

package com.example.demo.interceptor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    
    @Bean
    AuthInterceptor authInterceptor() {
        return new AuthInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        InterceptorRegistration addInterceptor = registry.addInterceptor(authInterceptor());
        // 排除配置
        addInterceptor.excludePathPatterns("/login**")
        .excludePathPatterns("/swagger**")
        .excludePathPatterns("/druid**");
        // 拦截配置
        addInterceptor.addPathPatterns("/**");
    }
}

WebApiConfig.java

package com.example.demo.interceptor;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class WebApiConfig extends WebMvcConfigurationSupport {

    /**
     * 添加静态资源--过滤swagger-api (开源的在线API文档)
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html")
        .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/");
        registry.addResourceHandler("/swagger-resources/**")
                .addResourceLocations("classpath:/META-INF/resources/swagger-resources/");
        registry.addResourceHandler("/swagger/**")
        .addResourceLocations("classpath:/META-INF/resources/swagger*");
        registry.addResourceHandler("/v2/api-docs/**")
                .addResourceLocations("classpath:/META-INF/resources/v2/api-docs/");

        registry.addResourceHandler("/druid/**").addResourceLocations("classpath:/META-INF/resources/");
        super.addResourceHandlers(registry);
    }

    /**
     * 跨域支持
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH")
                .allowCredentials(true).maxAge(3600);
    }
}

DruidStatFilter.java

package com.example.demo.druid;

import com.alibaba.druid.support.http.WebStatFilter;

import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

@WebFilter(filterName = "druidWebStatFilter", urlPatterns = "/*",
        initParams = {
        @WebInitParam(name = "exclusions",
                value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*") })
public class DruidStatFilter extends WebStatFilter {

}

DemoConfiguration .java

package com.example.demo.component;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.example.demo.exception.DemoException;
import com.example.demo.utils.StringUtil;

@Component
public class DemoConfiguration {
    private static final Logger logger = Logger.getLogger(DemoConfiguration.class);
    private static final Properties properties = new Properties();

    public DemoConfiguration() throws DemoException {
        InputStream inputStream = null;
        try {
            inputStream = this.getClass().getResourceAsStream("/wechat.properties");
            properties.load(inputStream);
            trimSpace(properties);
            inputStream.close();
        } catch (IOException e) {
            logger.error(StringUtil.formatErrorLogger(e, "CloudConfiguration"));
            throw new DemoException(e);
        }finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error(StringUtil.formatErrorLogger(e, "CloudConfiguration"));
                }
            }
        }
    }
 
    public int getJWTValidTimeLength() {
        return Integer.parseInt(properties.getProperty("JWT_VALID_TL_MINUTE"));
    }

    public int getJWTCheckTimeLength() {
        return Integer.parseInt(properties.getProperty("JWT_CHECK_TL_MINUTE"));
    }

    private void trimSpace(Properties properties) {
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            entry.setValue(entry.getValue().toString().trim());
        }
    }
}

JWTExecutor .java

package com.example.demo.component;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.entity.User;
import com.example.demo.exception.AuthorizationException;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

@Component
public class JWTExecutor {

    public static final String JWT_ID = "ctcloud_jwt";

    @Autowired
    private DemoConfiguration demoConfiguration;

    @Autowired
    private RSAGeneral rsaGeneral;

    public String createJWT(String subject) throws AuthorizationException {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256;
        long currentTimeMillis = System.currentTimeMillis();
        Date currentDate = new Date(currentTimeMillis);
        long expirationTimeMillis = currentTimeMillis + demoConfiguration.getJWTValidTimeLength() * 60 * 1000;
        Date expirationDate = new Date(expirationTimeMillis);

        PrivateKey privateKey = rsaGeneral.getPrivateKey();
        JwtBuilder builder = Jwts.builder()
            .setId(JWT_ID)
            .setNotBefore(currentDate)
            .setSubject(subject)
            .setExpiration(expirationDate)
            .signWith(signatureAlgorithm, privateKey);
        return builder.compact();
    }

    public Claims parseJWT(String jwt) throws AuthorizationException {
        PublicKey publicKey = rsaGeneral.getPublicKey();
        Claims claims = Jwts.parser()
           .setSigningKey(publicKey)
           .parseClaimsJws(jwt).getBody();
        return claims;
    }

    public String generalSubject(User user) {
        JSONObject json = new JSONObject();
        json.put("userName", user.getUserName());
        json.put("tokenStartTime", user.getTokenStartTime());
        return json.toJSONString();
    }

    public long geJWTCheckTimeMillis() {
        return demoConfiguration.getJWTCheckTimeLength() * 60 * 1000;
    }
}

RSAGeneral .java

package com.example.demo.component;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import com.example.demo.exception.AuthorizationException;
import com.example.demo.utils.StringUtil;

@Component
public class RSAGeneral {

    private static final String RSA_ALIAS = "appdemo";
    private static final String RSA_PASSWORD = "appdemo";
    private static final String RSA_CERT_TYPE = "X.509";
    private static final String RSA_STORE_TYPE = "JCEKS";
    private static final String RSA_CERT_FILE_EXTENSION = ".cert";
    private static final String RSA_STORE_FILE_EXTENSION = ".store";

    private Logger logger = Logger.getLogger(RSAGeneral.class);

    public PrivateKey getPrivateKey() throws AuthorizationException {
        char[] password = RSA_PASSWORD.toCharArray();
        InputStream inputStream = null;
        try {
            String storePath = "/rsa/" + RSA_ALIAS + RSA_STORE_FILE_EXTENSION;
            KeyStore keyStore = KeyStore.getInstance(RSA_STORE_TYPE);
            inputStream = this.getClass().getResourceAsStream(storePath);
            keyStore.load(inputStream, password);
            return (PrivateKey) keyStore.getKey(RSA_ALIAS, password);
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException
                | UnrecoverableKeyException e) {
            logger.error(StringUtil.formatErrorLogger(e, "getPrivateKey"));
            throw new AuthorizationException(e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error(StringUtil.formatErrorLogger(e, "getPrivateKey"));
            }
        }
    }

    public PublicKey getPublicKey() throws AuthorizationException {
        String certPath = "/rsa/" + RSA_ALIAS + RSA_CERT_FILE_EXTENSION;
        InputStream inputStream = null;
        try {
            CertificateFactory factory = CertificateFactory.getInstance(RSA_CERT_TYPE);
            inputStream = this.getClass().getResourceAsStream(certPath);
            Certificate certificate = factory.generateCertificate(inputStream);
            return certificate.getPublicKey();
        } catch (CertificateException e) {
            logger.error(StringUtil.formatErrorLogger(e, "getPublicKey"));
            throw new AuthorizationException(e);
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (IOException e) {
                logger.error(StringUtil.formatErrorLogger(e, "getPublicKey"));
            }
        }
    }
}

生成公钥和私钥

keytool -genkey -v -alias demo -dname "CN=demo,OU=wz,O=XAPSD,L=XA,ST=SX,C=CN" -keyalg RSA -keypass wechat -keystore ~/rsa/demo.store -storepass demo -validity 36500 -storetype JCEKS
keytool -genkey -v -alias appdemo -dname "CN=appdemo,OU=wz,O=XAPSD,L=XA,ST=SX,C=CN" -keyalg RSA -keypass appdemo -keystore ~/rsa/appdemo.store -storepass appdemo -validity 36500 -storetype JCEKS

Swagger2 .java

package com.example.demo.swagger;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * Swagger2 配置
 */
@Configuration
public class Swagger2 {

    @Value("${swagger.show}")
    private boolean swaggerShow;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerShow)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Swagger Restful API")
                .description("Swagger Restful API")
                .version("1.0")
                .build();
    }
}

utils代码

package com.example.demo.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

public class DataFormatUtils {
    private static final String JSON_ERROR = "error";
    private static final String JSON_CTMSG = "message";
    private static final String JSON_SUCCESS = "success";
    private static final String JSON_FAILURE = "failure";
    private static final String JSON_DATA = "data";
    private static final String SUBMIT_DATA = "submitData";
    public static final String UPDATE_JOBIDS = "updateJobIds";

    public static Map<String, Object> format(String message, Object obj, Object submitJobInfo) {
        Map<String, Object> objectMap = format(message, obj);
        objectMap.put(SUBMIT_DATA, submitJobInfo);
        return objectMap;
    }

    public static Map<String, Object> tokenFormat(String message, String token, Object obj) {
        Map<String, Object> objectMap = new HashMap<String, Object>();
        objectMap.put(DemoConstants.TOKEN_NAME, token);
        objectMap.put(JSON_ERROR, message);
        objectMap.put(JSON_DATA, obj);
        return objectMap;
    }

    public static Map<String, Object> tokenFormat(String message) {
        return tokenFormat(message, "", "");
    }

    public static Map<String, Object> format(String message, Object obj) {
        Map<String, Object> objectMap = new HashMap<String, Object>();
        objectMap.put(JSON_ERROR, message);
        objectMap.put(JSON_DATA, obj);
        return objectMap;
    }

    public static Map<String, Object> format(String message) {
        return format(message, "");
    }

    public static Map<String, Object> formatControl(List<String> success, List<String> failure,
            List<String> updateJobIds, String jobAction) {
        Map<String, Object> objectMap = new HashMap<String, Object>();
        Map<String, String> messageMap = new HashMap<String, String>();
        String successMsg = null;
        String failureMsg = null;
        if (success.size() > 0) {
            if (!jobAction.equalsIgnoreCase("bpeek")) {
                successMsg = StringUtils.join(success.toArray(), ";").replaceAll("\n", "");
            } else {
                successMsg = StringUtils.join(success.toArray(), "").replaceAll("<< output from stdout >>", "");
            }
        }
        if (failure.size() > 0) {
            failureMsg = StringUtils.join(failure.toArray(), ";").replaceAll("\n", "");
        }
        if (!(successMsg == null || successMsg.isEmpty()) || !(failureMsg == null || failureMsg.isEmpty())) {
            messageMap.put(JSON_SUCCESS, successMsg);
            messageMap.put(JSON_FAILURE, failureMsg);
        }
        objectMap.put(JSON_CTMSG, messageMap);
        if (updateJobIds.size() != 0) {
            objectMap.put(UPDATE_JOBIDS, StringUtils.join(updateJobIds.toArray(), ","));
        } else {
            objectMap.put(UPDATE_JOBIDS, null);
        }
        return objectMap;
    }
}

package com.example.demo.utils;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import com.example.demo.exception.DemoException;

final public class DesEncrypter {
    private static DesEncrypter desEncrypter = null;
    private Cipher ecipher = null;
    private Cipher dcipher = null;

    private Logger logger = Logger.getLogger(DesEncrypter.class);
    public DesEncrypter(String passPhrase) throws DemoException {
        try {
            KeySpec keySpec = new DESKeySpec(passPhrase.getBytes());
            SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(keySpec);

            ecipher = Cipher.getInstance("DES");
            dcipher = Cipher.getInstance("DES");

            ecipher.init(Cipher.ENCRYPT_MODE, key);
            dcipher.init(Cipher.DECRYPT_MODE, key);
        } catch (InvalidKeySpecException | NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException e) {
            logger.error(StringUtil.formatErrorLogger(e, "DesEncrypter", passPhrase));
            throw new DemoException(e);
        }
    }

    public String encrypt(String str) throws DemoException {
        byte[] utf8 = null;
        byte[] enc = null;
        try {
            utf8 = str.getBytes("UTF8");
            enc = ecipher.doFinal(utf8);
        } catch (UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
            logger.error(StringUtil.formatErrorLogger(e, "encrypt", str));
            throw new DemoException(e);
        }
        return new String(Base64.encodeBase64(enc));
    }

    public String decrypt(String str) throws DemoException {
        byte[] dec = null;
        byte[] utf8 = null;
        dec = Base64.decodeBase64(str);
        try {
            utf8 = dcipher.doFinal(dec);
            return new String(utf8, "UTF8");
        } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
            logger.error(StringUtil.formatErrorLogger(e, "decrypt", str));
            throw new DemoException(e);
        }
    }

    public synchronized static DesEncrypter getInstance() throws DemoException {
        if (desEncrypter == null) {
            desEncrypter = new DesEncrypter(".-'/W2@ce03=fky#vw6&H");
        }
        return desEncrypter;
    }

    public static void main(String[] args) throws DemoException {
        String passwd = args[0];
        String operateType = args[1];
        try {
            if (operateType.equals("dec")) {
                System.out.println(DesEncrypter.getInstance().decrypt(passwd));
            } else if (operateType.equals("enc")) {
                System.out.println(DesEncrypter.getInstance().encrypt(passwd));
            }
        } catch (DemoException e) {
            throw new DemoException(e.getMessage());
        }
    }
}

package com.example.demo.utils;

import java.math.BigDecimal;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.util.StringUtils;

public class StringUtil {

    private static final char[] CHAR_LIST = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
            'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
            'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4',
            '5', '6', '7', '8', '9' };

    public static List<String> trimSplitByComma(String param) {
        String[] params = param.split(",");
        List<String> result = new ArrayList<String>();
        for (String str : params) {
            if (isNotEmpty(str)) {
                result.add(str.trim());
            }
        }
        return result;
    }

    public static boolean isNotEmpty(String param) {
        return !isNullOrEmpty(param);
    }

    public static boolean isNullOrEmpty(String param) {
        if (param == null || param.trim().isEmpty()) {
            return true;
        } else {
            return false;
        }
    }

    public static String getStackTrace(Throwable th) {
        StringBuffer buffException = new StringBuffer();
        buffException.append(String.format("%s%n", th));
        for (StackTraceElement stackTrace : th.getStackTrace()) {
            if (stackTrace.getClassName().startsWith("com.clustertech.cloud")) {
                buffException.append(String.format("\t%s%n", stackTrace));
            }
        }
        return buffException.toString();
    }

    public static String formatErrorLogger(Throwable th, String methodName, String... params) {
        return String.format("Method={%s(%s)}%n%s", methodName, formateStringByComma(params), getStackTrace(th));
    }

    public static String formateHqlInData(String commaString) {
        String[] paramArray = commaString.trim().split(",");
        return formateStringByComma(paramArray);
    }

    public static String formateHqlInData(Collection<String> params) {
        String[] paramArray = params.toArray(new String[params.size()]);
        return formateStringByComma(paramArray);
    }

    public static String formateHqlInData(String[] params) {
        return formateStringByComma(params);
    }

    public static String formateStringByComma(String... params) {
        if (params == null || params.length <= 0) {
            return "";
        }

        StringBuffer buff = new StringBuffer();
        for (String param : params) {
            String result = param == null ? "null" : param.trim();
            buff.append("'" + result + "',");
        }
        return buff.substring(0, buff.length() - 1);
    }

    public static String converteArrayToString(String[] params) {
        if (params == null || params.length <= 0) {
            return "[]";
        }

        StringBuffer buff = new StringBuffer();
        buff.append("[");
        for (String param : params) {
            String result = param == null ? "null" : param.trim();
            buff.append(result + ", ");
        }
        buff.append("]");
        return buff.delete(buff.length() - 3, buff.length() - 1).toString();
    }

    public static String getRandomChar() {
        return getRandomChar(8);
    }

    public static String getRandomChar(int capacity) {
        StringBuffer sb = new StringBuffer(capacity);
        char c = ' ';
        do {
            c = CHAR_LIST[new SecureRandom().nextInt(CHAR_LIST.length)];
            sb.append(c);
        } while (sb.indexOf(String.valueOf(c)) != -1 && sb.length() < capacity);
        return sb.toString();
    }

    public static String[] converteMapToArray(Map<String, String> map) {
        if (map == null || map.isEmpty()) {
            return new String[0];
        }

        String[] arr = new String[map.size()];
        int i = 0;
        for (Entry<String, String> entry : map.entrySet()) {
            arr[i] = entry.getKey() + "=" + entry.getValue();
            i++;
        }
        return arr;
    }

    public static String getPastTime(Object interval) {
        Date currentDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);
        calendar.add(Calendar.HOUR, -Integer.parseInt(interval.toString()));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(calendar.getTime());
    }

    public static String dateFormat(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(date);
    }

    public static Date dateParse(String date) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(date);
    }

    public static String substringAfterLast(String str, String separator) {
        if (StringUtils.isEmpty(str) || StringUtils.isEmpty(separator)) {
            return "";
        }
        int pos = str.lastIndexOf(separator);
        if (pos == -1 || pos == (str.length() - separator.length())) {
            return "";
        }
        return str.substring(pos + separator.length());
    }

    public static String dataFormater(String data) {
        BigDecimal bd;
        BigDecimal dataFormated;
        bd = new BigDecimal(Double.valueOf(data));
        if (Double.valueOf(data) < 0.01) {
            dataFormated = bd.setScale(4, BigDecimal.ROUND_HALF_UP);
        } else {
            dataFormated = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
        }
        return dataFormated.toString();
    }
}

package com.example.demo.utils;

import java.util.ArrayList;
import java.util.List;

public class UrlDataUtil {
    private static final List<String> controllerMethodNames = new ArrayList<String>();

    /*
     * The data use hard code due to the controller method which not handled is never changed after develope,
     * and this method is the fastest way to get not handled data.
     */
    static {
        controllerMethodNames.add("/login");
        controllerMethodNames.add("/logout");
        controllerMethodNames.add("/user");
        // for swagger2
        controllerMethodNames.add("/swagger-ui.html");
        controllerMethodNames.add("/swagger-resources");
        controllerMethodNames.add("/v2/api-docs");
        controllerMethodNames.add("/configuration/ui");
        controllerMethodNames.add("/configuration/security");
        // for druid
        controllerMethodNames.add("/druid");
    }

    public static List<String> getData(){
        return controllerMethodNames;
    }
}

demo源码[email protected]:wz18567908/demo.git
参考博客https://blog.csdn.net/Winter_chen001/article/details/80266339

猜你喜欢

转载自blog.csdn.net/wz122330/article/details/87865451