概述
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
扫描二维码关注公众号,回复:
5463551 查看本文章
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