1.添加依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.6</version> </parent> <dependencies> <!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--模板--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--get set--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--mybatisplus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> <!--自动生成器--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.2</version> </dependency> <!--模板jsp页面转换成静态页面,为用户的访问节省时间,同样减少服务器的压力。--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> <!--swagger前后端分离工具--> <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> <!--MD5加密加盐--> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>5.6.1</version> </dependency> <!--jjwt认证--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <!--json--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.73</version> </dependency> <!--测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <!--打包--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
2.yml配置
server: port: 8888 spring: datasource: username: root password: 1234 url: jdbc:mysql:///ksgl jackson: date-format: yyyy-MM-dd time-zone: GMT+8 mvc: hiddenmethod: filter: enabled: true logging: level: cn.kgc: debug mybatis-plus: configuration: map-underscore-to-camel-case: true
3.代码生成器
String url = "jdbc:mysql:///ksgl"; String username = "root"; String password = "1234"; String author = "kgc"; String outputDir = "D:\\java2109springclound\\brucee\\src\\main\\java"; String parent = "cn.kgc"; String moduleName = "user_info"; String outputFile = "D:\\java2109springclound\\brucee\\src\\main\\resources\\mapper\\"+moduleName; List<String> tables = Arrays.asList("user_info"); String prefix = ""; FastAutoGenerator.create(url, username, password) .globalConfig(builder -> { builder.author(author) // 设置作者 // .enableSwagger() // 开启 swagger 模式 // .fileOverride() // 覆盖已生成文件 .outputDir(outputDir); // 指定输出目录 }) .packageConfig(builder -> { builder.parent(parent) // 设置父包名 .moduleName(moduleName) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.xml, outputFile)); // 设置mapperXml生成路径 }) .strategyConfig(builder -> { builder.addInclude(tables) // 设置需要生成的表名 .addTablePrefix(prefix); // 设置过滤表前缀 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 .execute();
4.登录之前
4.1 swagger类
实体类加注解@ApiOperation("用户信息")
属性加注解@ApiModelProperty("用户编号")
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build(); } private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("考试管理系统接口文档") .description("考试管理系统接口文档") .version("1.0") .build(); } }
4.2 返回描述类
@Data @NoArgsConstructor @AllArgsConstructor public class Result<T> implements Serializable { private Integer code; private String message; private T data; public static <T> Result<T> success(){ return new Result<>(20000,"success",null); } public static <T> Result<T> success(T data){ return new Result<>(20000,"success",data); } public static <T> Result<T> success(String message, T data){ return new Result<>(20000,message,data); } public static <T> Result<T> success(String message){ return new Result<>(20000,message,null); } public static <T> Result<T> fail(){ return new Result<>(20000,"fail",null); } public static <T> Result<T> fail(Integer code){ return new Result<>(code,"fail",null); } public static <T> Result<T> fail(Integer code, String message){ return new Result<>(code,message,null); } }
4.3 配置
@Configuration public class SeviriConfig { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } }
4.4 iterceptor.JwtInterceptor 登录凭证类
@Component @Slf4j public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getParameter("token"); if(token == null){ token = request.getHeader("X-Token"); } log.debug("token:------------"+token); //如果jwt则没有登录 if(token == null){ Result<Object> result = Result.fail(2004, "未登录"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(JSON.toJSONString(result)); return false; } //验证jwt的有效性 try { JwtUtil.parseJwt(token, UserInfo.class); }catch (Exception e){ e.printStackTrace(); Result<Object> result = Result.fail(20005,"登录凭证无效"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write(JSON.toJSONString(result)); return false; } return true; } }
4.5 utils.JwtUtil类 创建jwt 配置头部信息 id 签名 过期时间
public class JwtUtil { private JwtUtil(){} public static String createJwt(Object subject){ long exp = System.currentTimeMillis() + (1 * 60 * 60 * 1000); JwtBuilder builder = Jwts.builder(); //头部类型 builder.setHeaderParam("typ","JWT") //算法名称 .setHeaderParam("alg", SignatureAlgorithm.HS256) //载荷 放置数据 登录 用户名角色信息 .setSubject(JSON.toJSONString(subject)) //有效期 直接newdate就是当前 所以得在外面定义来计算 .setExpiration(new Date(exp)) //设置id 保证独一无二 .setId(UUID.randomUUID()+"") //签发者 .setIssuer("system") //签名 .signWith(SignatureAlgorithm.HS256,"123456"); return builder.compact(); } public static <T> T parseJwt(String jwt,Class<T>clazz){ JwtParser parser = Jwts.parser(); String subject = parser.setSigningKey("123456").parseClaimsJws(jwt).getBody().getSubject(); System.out.println(subject); return JSON.parseObject(subject,clazz); } private static Key encrypt(String key){ SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "AES"); return secretKeySpec; } }
5.0 user控制器 登录
@RestController @Api(tags = {"考试模块"}) @Slf4j @RequestMapping("/user_info/userInfo") public class UserInfoController { @Autowired private IUserInfoService userInfoService; @Autowired private PasswordEncoder passwordEncoder; @ApiOperation("登录") @PostMapping("/login") public Result<Map<String,Object>> login(@RequestBody UserInfo param){ UserInfo user = userInfoService.getUserByName(param.getUsername()); if(user == null){ return Result.fail(20002,"用户名或密码错误"); } //密码判断 boolean matches = passwordEncoder.matches(param.getPassword(), user.getPassword()); if(!matches){ return Result.fail(20004,"用户名或密码错误"); } Map<String,Object> data = new HashMap<>(); user.setPassword(null); data.put("token", JwtUtil.createJwt(user)); return Result.success(data); } @ApiOperation("获取用户信息") @GetMapping("/info") public Result<Map<String,Object>> getUserInfo(@RequestParam("token")String token){ UserInfo userInfo = JwtUtil.parseJwt(token, UserInfo.class); Map<String,Object> data = new HashMap<>(); data.put("roles", Arrays.asList(userInfo.getRole().split("."))); data.put("name",userInfo.getUsername()); data.put("avatar",userInfo.getAvatar()); return Result.success(data); } }
6 userservice实现类
@Override public UserInfo getUserByName(String username) { QueryWrapper<UserInfo> wrapper = new QueryWrapper<>(); wrapper.eq("username",username); return this.baseMapper.selectOne(wrapper); }