Maven 依赖汇总
Lombok
用处:一个注解完成大量的 get、set 操作,推荐用 properties 标签管理版本
1 2 3 4 5 6 7 8 9
| <properties> <lombok.version>1.18.4</lombok.version> </properties>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency>
|
单元测试
springboot 中直接引入 starter-test 即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
|
Fastjson2
推荐使用 2 版本
1 2 3 4 5
| <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.7</version> </dependency>
|
PageHelper 分页
1 2 3 4 5
| <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.0</version> </dependency>
|
JWT Token
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.10.3</version> </dependency>
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
|
MD5 加密
1 2 3 4
| <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency>
|
MyBatis 代码生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.1</version> </dependency>
<dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency>
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.4.3.4</version> </dependency>
|
AOP 日志
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
|
Swagger2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency>
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency>
|
Knife4j
1 2 3 4 5
| <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.9</version> </dependency>
|
工具类代码
JWTUtils - Token 工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.nwa.until;
import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.JWTVerifier;
import java.util.Date; import java.util.HashMap; import java.util.Map;
public class JWTUtils { private static final long EXPIRE_DATE = 30 * 610 * 100000; private static final String TOKEN_SECRET = "LuckyNWA666";
public static String token(String username, String password) { try { Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE); Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); Map<String, Object> header = new HashMap<>(); header.put("typ", "JWT"); header.put("alg", "HS256"); return JWT.create() .withHeader(header) .withClaim("username", username) .withClaim("password", password) .withExpiresAt(date) .sign(algorithm); } catch (Exception e) { e.printStackTrace(); return null; } }
public static boolean verify(String token) { try { Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET); JWTVerifier verifier = JWT.require(algorithm).build(); verifier.verify(token); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }
|
MD5Utils - 加密工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.nwa.until;
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class MD5Utils { public static String md5(String pwd) { try { MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(pwd.getBytes()); return new BigInteger(1, md5.digest()).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } }
|
CodeGenerator - 代码生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package com.nwa.until;
import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.OutputFile; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Collections;
public class CodeGenerator { public static void main(String[] args) { FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/weeklydb?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC", "root", "123456") .globalConfig(builder -> { builder.author("luckyNwa") .enableSwagger() .fileOverride() .outputDir(System.getProperty("user.dir") + "/src/main/java"); }) .packageConfig(builder -> { builder.parent("com.nwa") .moduleName("") .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper")); }) .strategyConfig(builder -> { builder.addInclude("tb_weeks") .addTablePrefix("tb_", "sys_"); }) .templateEngine(new FreemarkerTemplateEngine()) .execute(); } }
|
SwaggerConfig - Swagger 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.nwa.until;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiKey; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList; import java.util.List;
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket docket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.nwa.controller")) .build() .securitySchemes(security()); }
private ApiInfo apiInfo() { Contact luckyNWA = new Contact("luckyNWA", "www.nwa.com", "1656213092@qq.com"); return new ApiInfo( "小维的API接口说明", "此文档详细说明了小维前后端项目端口规范", "v1.0", "www.nwa.com", luckyNWA, "apache 2.0", "www.nwa.com", new ArrayList() ); }
private List<ApiKey> security() { ArrayList<ApiKey> list = new ArrayList<>(); list.add(new ApiKey("token", "token", "header")); return list; } }
|
Knife4jConfiguration - Knife4j 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| package com.nwa.config;
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; 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.service.ApiKey; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.util.List;
import static com.github.xiaoymin.knife4j.core.util.CollectionUtils.newArrayList;
@Configuration @AllArgsConstructor @EnableSwagger2WebMvc public class Knife4jConfiguration { private final OpenApiExtensionResolver openApiExtensionResolver;
@Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build() .extensions(openApiExtensionResolver.buildSettingExtensions()) .securitySchemes(security()); }
private List<ApiKey> security() { return newArrayList(new ApiKey("Token", "token", "header")); }
private ApiInfo apiInfo() { Contact luckyNWA = new Contact("luckyNWA", "http://luckynwa.top", "1656213092@qq.com"); return new ApiInfoBuilder() .title("小维的API接口说明") .description("多个应用系统之间的身份验证和访问控制的接口") .termsOfServiceUrl("http://luckynwa.top") .version("1.0") .contact(luckyNWA) .license("apache 2.0") .build(); } }
|
CheckTokenInterceptor - Token 拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.nwa.until;
import com.fasterxml.jackson.databind.ObjectMapper; import com.nwa.bean.ResultVO; import io.jsonwebtoken.*; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;
@Component public class CheckTokenInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { String method = request.getMethod(); if ("OPTIONS".equalsIgnoreCase(method)) { return true; } String token = request.getHeader("token"); if (token == null) { ResultVO resultVO = new ResultVO(ResStatus.FAIL, "请先登录", null); doResponse(response, resultVO); } else { try { return JWTUtils.verify(token); } catch (ExpiredJwtException e) { doResponse(response, new ResultVO(ResStatus.FAIL, "登录过期", null)); } catch (UnsupportedJwtException e) { doResponse(response, new ResultVO(ResStatus.FAIL, "token不合法", null)); } catch (Exception e) { doResponse(response, new ResultVO(ResStatus.FAIL, "请先登录", null)); } } return false; }
private void doResponse(HttpServletResponse response, ResultVO resultVO) throws IOException { response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println(new ObjectMapper().writeValueAsString(resultVO)); out.flush(); out.close(); } }
|
SysLog - 自定义日志注解
1 2 3 4 5 6 7 8 9 10 11 12
| package com.nwa.aop;
import java.lang.annotation.*;
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SysLog { String operationType() default ""; String operationName() default ""; String value() default ""; }
|
SysLogA - AOP 日志切面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package com.nwa.aop;
import com.nwa.bean.Client; import com.nwa.service.impl.SysLogService; import com.nwa.until.ClientInfoUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.util.Date;
@Slf4j @Aspect @Component public class SysLogA { @Resource private SysLogService sysLogService;
@Pointcut("execution(* com.nwa.controller.IndexController.*(..))") public void logPointCut() { }
@After("logPointCut()") public void logTest(JoinPoint joinPoint) throws Exception { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String browser = ClientInfoUtil.getBrowserInfo(request); String os = ClientInfoUtil.getOperatingSystem(request); String ip = ClientInfoUtil.getIP(request);
try { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); SysLog sysLog = method.getAnnotation(SysLog.class);
Client client1 = new Client(); client1.setCreateBy(sysLog.operationType()); client1.setRequestIp(ip); client1.setLogTip(sysLog.operationName()); client1.setLogSys(os); client1.setLogBrowser(browser); client1.setCreateDate(new Date()); sysLogService.save(client1); } catch (Exception e) { log.error("==后置通知异常=="); log.error("异常信息:{}------" + e.getMessage()); throw e; } } }
|
配置参考
拦截器配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package com.nwa.until;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Autowired private CheckTokenInterceptor checkTokenInterceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(checkTokenInterceptor) .addPathPatterns("/home/**") .excludePathPatterns("/index/**", "/home/getLogList", "/swagger-ui/**", "/swagger2.html", "/doc.html"); }
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("doc.html") .addResourceLocations("classpath:/META-INF/resources/"); } }
|
Knife4j YML 配置
1 2 3 4 5 6 7 8 9 10 11
| knife4j: enable: true production: false basic: enable: false username: test password: 123 setting: enableSearch: false enableHomeCustom: true homeCustomLocation: classpath:markdown/home.md
|
前端 Token 配置
1 2 3 4 5 6 7 8 9 10 11 12 13
| window.sessionStorage.setItem('token', data.token)
request.interceptors.request.use( (config) => { config.headers.token = window.sessionStorage.getItem('token') return config }, (error) => { return Promise.reject(error) }, )
|
使用示例
Lombok 实体类
1 2 3 4 5 6 7 8 9 10 11
| import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
@Data @NoArgsConstructor @AllArgsConstructor public class Client { private int userAcc; private String userPwd; }
|
单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class TestWiring { @Resource private DeviceTopoService deviceTopoService;
@Test public void fun1() { DeviceTopoEntity info = deviceTopoService.getById(1); log.info(String.valueOf(info)); } }
|
PageHelper 分页
1 2 3 4 5 6 7 8 9 10 11
| @Override public ResultVO getMyWeekList(String months, String id, int page, int limit) { PageHelper.startPage(page, limit); List<Client> clientS = adHomeMapper.getMyWeekList(months, id); if (clientS != null) { PageInfo<Client> pageInfo = new PageInfo<>(clientS, 3); int count = (int) pageInfo.getTotal(); return new ResultVO(ResStatus.OK, "列表信息返回成功!", count, clientS); } return resultVO; }
|
Fastjson2 接收参数
1 2 3 4 5 6
| @PostMapping("/login") public ResultVO loginHome(@RequestBody JSONObject obj) { String userAcc = obj.getString("userAcc"); String userPwd = obj.getString("userPwd"); return indexService.login(userAcc, userPwd); }
|
Swagger 注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Api(value = "提供了后台主页面的各种接口", tags = "后台主页面接口")
@ApiOperation("修改密码") @ApiImplicitParams({ @ApiImplicitParam(dataType = "string", name = "userAcc", value = "账号", required = true), @ApiImplicitParam(dataType = "string", name = "newPassword", value = "新密码", required = true), }) @PutMapping("/modifyPwd")
@ApiModel(value = "周报里面的实体", description = "封装的周报对象") @ApiModelProperty("用户id")
|