格式化了代码,添加了全局异常处理和Redis相关配置,取消了LoginException,POM解决了爆红问题

master
ArgonarioD 2022-06-29 11:32:33 +08:00
parent 1397496bc3
commit 2c9a880c23
15 changed files with 164 additions and 57 deletions

View File

@ -142,6 +142,7 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.1</version>
<configuration> <configuration>
<excludes> <excludes>
<exclude> <exclude>

View File

@ -0,0 +1,33 @@
package cn.edu.hfut.rmdjzz.projectmanagement.advice;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.TokenException;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @author
* @since 2022/6/29 1:00
*/
@Slf4j
@RestControllerAdvice
public class ExceptionHandlerAdvice {
@ExceptionHandler(TokenException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
public ResponseMap handleTokenException(TokenException e) {
// log.error(ExceptionUtils.getStackTrace(e));
log.error(e.getMessage());
return ResponseMap.of(HttpStatus.UNAUTHORIZED.value(), e.getMessage());
}
@ExceptionHandler(BadRequestException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseMap handleBadRequestException(BadRequestException e) {
log.error(e.getMessage());
return ResponseMap.of(HttpStatus.BAD_REQUEST.value(), e.getMessage());
}
}

View File

@ -0,0 +1,33 @@
package cn.edu.hfut.rmdjzz.projectmanagement.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import javax.annotation.Resource;
/**
* @author
* @since 2022/6/28 17:48
*/
@Configuration
public class RedisConfig {
@Resource
RedisConnectionFactory factory;
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(RedisSerializer.json());
template.setValueSerializer(RedisSerializer.json());
template.setHashKeySerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());
template.afterPropertiesSet();
return template;
}
}

View File

@ -23,7 +23,9 @@ public class WebConfig implements WebMvcConfigurer {
registry.addInterceptor(corsInterceptor).addPathPatterns("/**"); registry.addInterceptor(corsInterceptor).addPathPatterns("/**");
registry.addInterceptor(new TokenInterceptor()) registry.addInterceptor(new TokenInterceptor())
.addPathPatterns("/**") .addPathPatterns("/**")
.excludePathPatterns("/api/login"); .excludePathPatterns("/staff/login")
.excludePathPatterns("/hello")
.excludePathPatterns("/staff/hello2");
} }
/* /*
@Override @Override

View File

@ -1,10 +1,9 @@
package cn.edu.hfut.rmdjzz.projectmanagement.controller; package cn.edu.hfut.rmdjzz.projectmanagement.controller;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException;
import cn.edu.hfut.rmdjzz.projectmanagement.service.impl.StaffServiceImpl; import cn.edu.hfut.rmdjzz.projectmanagement.service.impl.StaffServiceImpl;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
import com.fasterxml.jackson.core.JsonProcessingException; import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -16,13 +15,19 @@ import org.springframework.web.bind.annotation.RestController;
* created at 2022/6/28 21:59 * created at 2022/6/28 21:59
*/ */
@RestController @RestController
@RequestMapping("/api") @RequestMapping("/staff")
public class StaffController { public class StaffController {
@Autowired @Autowired
private StaffServiceImpl staffServiceImpl; private StaffServiceImpl staffServiceImpl;
@SneakyThrows
@PostMapping("/login") @PostMapping("/login")
public ResponseMap login(@RequestBody Staff staff) throws LoginException, JsonProcessingException { public ResponseMap login(@RequestBody Staff staff) {
return staffServiceImpl.login(staff.getStaffUsername(), staff.getStaffPassword()); return staffServiceImpl.login(staff.getStaffUsername(), staff.getStaffPassword());
} }
@RequestMapping("/hello2")
public ResponseMap hello2(@RequestBody Staff str) {
return ResponseMap.ofSuccess("adada", str);
}
} }

View File

@ -0,0 +1,9 @@
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
/**
* @author
* created at 2022/6/28 21:24
*/
public class BadRequestException extends Exception{
public BadRequestException(String message){super(message);}
}

View File

@ -1,9 +0,0 @@
package cn.edu.hfut.rmdjzz.projectmanagement.exception;
/**
* @author
* created at 2022/6/28 21:24
*/
public class LoginException extends Exception{
public LoginException(String message){super(message);}
}

View File

@ -1,6 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.interceptor; package cn.edu.hfut.rmdjzz.projectmanagement.interceptor;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.HandlerInterceptor;
@ -18,12 +19,11 @@ public class CorsInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*"); response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "content-type,token"); response.setHeader("Access-Control-Allow-Headers", "Content-Type,Token");
response.setHeader("Content-Type", "application/json;charset=utf-8");
response.setHeader("Access-Control-Allow-Credentials","false"); response.setHeader("Access-Control-Allow-Credentials","false");
// 如果是OPTIONS则结束请求 // 如果是OPTIONS则结束请求
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) { if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
response.setStatus(200); response.setStatus(HttpStatus.OK.value());
return false; return false;
} }

View File

@ -6,6 +6,7 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
@ -20,14 +21,14 @@ import java.io.IOException;
* @author * @author
* created at 2022/6/28 18:16 * created at 2022/6/28 18:16
*/ */
//FIXME: objectMapper去掉
@Component @Component
public class TokenInterceptor implements HandlerInterceptor { public class TokenInterceptor implements HandlerInterceptor {
@Resource
private ObjectMapper objectMapper;
@Override @Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws TokenException, IOException { public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws TokenException, IOException {
System.out.println(httpServletRequest.getRequestURL()+" "+httpServletRequest.getMethod()); System.out.println(httpServletRequest.getRequestURL()+" "+httpServletRequest.getMethod());
if (!(object instanceof HandlerMethod)) { throw new TokenException("in token");
/*if (!(object instanceof HandlerMethod)) {
return false; return false;
} }
String token = httpServletRequest.getHeader("Token"); String token = httpServletRequest.getHeader("Token");
@ -47,6 +48,6 @@ public class TokenInterceptor implements HandlerInterceptor {
return false; return false;
} }
httpServletResponse.setHeader("Token",TokenUtils.autoRequire(token)); httpServletResponse.setHeader("Token",TokenUtils.autoRequire(token));
return true; return true;*/
} }
} }

View File

@ -1,15 +1,14 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service; package cn.edu.hfut.rmdjzz.projectmanagement.service;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap; import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.fasterxml.jackson.core.JsonProcessingException;
/** /**
* @author * @author
* @since 2022/6/28 17:28 * @since 2022/6/28 17:28
*/ */
public interface IStaffService extends IService<Staff> { public interface IStaffService extends IService<Staff> {
ResponseMap login(String username, String password) throws LoginException, JsonProcessingException; ResponseMap login(String username, String password) throws BadRequestException;
} }

View File

@ -1,7 +1,7 @@
package cn.edu.hfut.rmdjzz.projectmanagement.service.impl; package cn.edu.hfut.rmdjzz.projectmanagement.service.impl;
import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff; import cn.edu.hfut.rmdjzz.projectmanagement.entity.Staff;
import cn.edu.hfut.rmdjzz.projectmanagement.exception.LoginException; import cn.edu.hfut.rmdjzz.projectmanagement.exception.BadRequestException;
import cn.edu.hfut.rmdjzz.projectmanagement.mapper.StaffMapper; import cn.edu.hfut.rmdjzz.projectmanagement.mapper.StaffMapper;
import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService; import cn.edu.hfut.rmdjzz.projectmanagement.service.IStaffService;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils; import cn.edu.hfut.rmdjzz.projectmanagement.utils.TokenUtils;
@ -9,13 +9,9 @@ import cn.edu.hfut.rmdjzz.projectmanagement.utils.response.ResponseMap;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
/** /**
* @author * @author
* @since 2022/6/28 17:29 * @since 2022/6/28 17:29
@ -24,23 +20,24 @@ import javax.annotation.Resource;
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService { public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements IStaffService {
@Override @Override
public ResponseMap login(String username, String password) throws LoginException, JsonProcessingException { public ResponseMap login(String username, String password) throws BadRequestException {
if(username==null||username.trim().length()==0) if (username == null || username.trim().length() == 0)
throw new LoginException("用户名为空"); throw new BadRequestException("用户名为空");
else if(!username.equals(username.replaceAll("[^a-zA-Z0-9]", ""))) else if (!username.equals(username.replaceAll("[^a-zA-Z0-9]", "")))
throw new LoginException("用户名格式错误"); throw new BadRequestException("用户名格式错误");
else if(password==null||password.trim().length()!=32) else if (password == null || password.trim().length() != 32)
throw new LoginException("密码格式错误"); throw new BadRequestException("密码格式错误");
Staff staff = getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffUsername,username));
if(staff==null) Staff staff = getOne(Wrappers.<Staff>lambdaQuery().eq(Staff::getStaffUsername, username));
throw new LoginException("用户不存在"); if (staff == null)
password= DigestUtils.md5DigestAsHex((password+staff.getStaffSalt()).getBytes()); throw new BadRequestException("用户不存在");
if(!staff.getStaffPassword().equals(password)) password = DigestUtils.md5DigestAsHex((password + staff.getStaffSalt()).getBytes());
throw new LoginException("密码错误"); if (!staff.getStaffPassword().equals(password))
ResponseMap res=ResponseMap.ofSuccess("ok").put("username",username); throw new BadRequestException("密码错误");
res.put("Token",TokenUtils.getToken(staff.getStaffUsername(),staff.getStaffId())); return ResponseMap.ofSuccess("ok")
res.put("staffFullname",staff.getStaffFullname()); .put("Token", TokenUtils.getToken(staff.getStaffUsername(), staff.getStaffId()))
res.put("staffId",staff.getStaffId()); .put("staffUsername", username)
return res; .put("staffFullname", staff.getStaffFullname())
.put("staffId", staff.getStaffId());
} }
} }

View File

@ -15,16 +15,18 @@ import java.util.Date;
*/ */
//TODO: 演示的时候把expireTime改短点儿 //TODO: 演示的时候把expireTime改短点儿
public final class TokenUtils { public final class TokenUtils {
public final static String pvKey="SignedByRMDJZZ"; public final static String pvKey = "SignedByRMDJZZ";
public static String getToken(String username,Integer staffId){
public static String getToken(String username, Integer staffId) {
return JWT.create() return JWT.create()
.withClaim("username", username) .withClaim("username", username)
.withClaim("staffId", staffId) .withClaim("staffId", staffId)
.withIssuedAt(new Date()) .withIssuedAt(new Date())
.withExpiresAt(new Date(System.currentTimeMillis() + 5*60*60*1000)) .withExpiresAt(new Date(System.currentTimeMillis() + 5 * 60 * 60 * 1000))
.sign(Algorithm.HMAC256(pvKey)); .sign(Algorithm.HMAC256(pvKey));
} }
public static boolean checkToken(String token) throws TokenException { public static boolean checkToken(String token) throws TokenException {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(pvKey)).build(); JWTVerifier verifier = JWT.require(Algorithm.HMAC256(pvKey)).build();
try { try {
@ -34,24 +36,29 @@ public final class TokenUtils {
throw new TokenException("非法的Token"); throw new TokenException("非法的Token");
} }
} }
public static boolean checkTimeOut(String token) throws TokenException { public static boolean checkTimeOut(String token) throws TokenException {
if(!checkToken(token)) if (!checkToken(token))
return true; return true;
return JWT.decode(token).getClaim("exp").asLong()<(System.currentTimeMillis()/1000); return JWT.decode(token).getClaim("exp").asLong() < (System.currentTimeMillis() / 1000);
} }
public static String getUsername(String token) throws TokenException { public static String getUsername(String token) throws TokenException {
if(!checkToken(token)) if (!checkToken(token))
return null; return null;
return JWT.decode(token).getClaim("username").asString(); return JWT.decode(token).getClaim("username").asString();
} }
public static Integer getStaffId(String token) throws TokenException { public static Integer getStaffId(String token) throws TokenException {
if(!checkToken(token)) if (!checkToken(token))
return null; return null;
return JWT.decode(token).getClaim("staffId").asInt(); return JWT.decode(token).getClaim("staffId").asInt();
} }
public static String refreshToken(String token) throws TokenException { public static String refreshToken(String token) throws TokenException {
return getToken(getUsername(token),getStaffId(token)); return getToken(getUsername(token), getStaffId(token));
} }
public static String autoRequire(String token) throws TokenException { public static String autoRequire(String token) throws TokenException {
boolean check = checkToken(token); boolean check = checkToken(token);
if (check) { if (check) {

View File

@ -2,14 +2,12 @@ package cn.edu.hfut.rmdjzz.projectmanagement.utils.response;
import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils; import cn.edu.hfut.rmdjzz.projectmanagement.utils.BeanUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import org.springframework.core.serializer.support.SerializationFailedException; import org.springframework.core.serializer.support.SerializationFailedException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import javax.annotation.Resource;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -26,6 +24,7 @@ public class ResponseMap {
private Integer code; private Integer code;
private String msg; private String msg;
private Map<String, Object> data; private Map<String, Object> data;
/** /**
* *
* *

View File

@ -10,6 +10,8 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author * @author
@ -31,5 +33,11 @@ public class MybatisPlusTests {
staffService.getOne(Wrappers.<Staff>query().last("limit 1")) staffService.getOne(Wrappers.<Staff>query().last("limit 1"))
) )
)); ));
Map<Object, Object> map = new HashMap<>();
map.put("123", "456");
map.put(894, 789);
System.out.println(objectMapper.writeValueAsString(
ResponseMap.ofSuccess("ok", map)
));
} }
} }

View File

@ -0,0 +1,22 @@
package cn.edu.hfut.rmdjzz.projectmanagement;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import javax.annotation.Resource;
/**
* @author
* @since 2022/6/28 23:10
*/
@SpringBootTest
public class RedisTests {
@Resource
private RedisTemplate<Object, Object> redisTemplate;
@Test
void test(){
redisTemplate.opsForList().rightPush(123456,89);
}
}