外观
Springboot常用工具集配置
1. 简介
2. 常用工具集
Redis序列化配置
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
FastJson配置
@Bean
public HttpMessageConverters fastJsonHttpMessageConverter(){
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setDateFormat(DatePattern.NORM_DATETIME_PATTERN);
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullListAsEmpty);
// 3处理中文乱码问题
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
converter.setSupportedMediaTypes(fastMediaTypes);
converter.setFastJsonConfig(fastJsonConfig);
return new HttpMessageConverters(converter);
}
AOP全局异常处理
@RestControllerAdvice
@Slf4j
public class ResponseBodyChecker implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof Response) {
Response res = (Response) body;
response.setStatusCode(HttpStatus.valueOf(res.getStatus()));
} else {
log.warn(">> We suggest you use Response object return result.");
}
return body;
}
@ExceptionHandler(value = BizException.class)
@ResponseBody
public Response nullExceptionHandler(HttpServletRequest req, BizException e) {
log.error(">> Business exception: ", e);
return Response.error("系统发生业务异常!" + e.getMessage());
}
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public Response nullExceptionHandler(HttpServletRequest req, NullPointerException e) {
log.error(">> System null pointer: ", e);
return Response.error("系统发生空指针异常!请联系技术人员处理。");
}
/**
* @param req
* @return Response
* @description 默认异常处理
* @author PengHao
* @date 2023-07-07 15:38:25
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public Response exceptionHandler(HttpServletRequest req, Exception e) {
log.error(">> System exception: {}", e);
return Response.error("系统发生未知异常!请联系技术人员处理。");
}
}
Redis工具类封装
/**
* @description: redis 客户端
* @author: PengHao
* @date: 2023/8/8 09:14:03
* @version: v1.0
*/
@Component
public class RedisCache {
/**
* redis key :用户token hash key
*/
public static final String REDIS_KEY_LOGIN_TOKEN = "login:token";
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* @description 一句话描述
* @param key
* @param hashKey
* @return null
* @author PengHao
* @date 2023-08-08 09:18:39
*/
public <T> T getHashObject(String key, String hashKey, Class<T> clazz){
JSONObject userJson = (JSONObject) redisTemplate.opsForHash().get(key, hashKey);
return JSONObject.toJavaObject(userJson, clazz);
}
public void putHashObject(String key, String hashKey, Object val){
redisTemplate.opsForHash().put(key, hashKey, val);
}
public Long delHashObject(String key, String ...hashKey){
return redisTemplate.opsForHash().delete(key, hashKey);
}
public Boolean delete(String ...key){
if (key.length == 1){
return redisTemplate.delete(key[0]);
} else {
return redisTemplate.delete(Arrays.asList(key)) > 0;
}
}
public Boolean expire(String key,long time){
return redisTemplate.expire(key,time, TimeUnit.MINUTES);
}
public long getExpire(String key){
return redisTemplate.getExpire(key);
}
public void put(String key, Object value){
redisTemplate.opsForValue().set(key, value);
}
public void put(String key, Object value, Duration duration){
redisTemplate.opsForValue().set(key, value, duration);
}
public Object get(String key){
return redisTemplate.opsForValue().get(key);
}
public void putList(String key, Object ...value){
redisTemplate.opsForList().rightPushAll(key, value);
}
public List<?> getList(String key, int count){
return redisTemplate.opsForList().rightPop(key, count);
}
public Boolean hashKey(String key){
return redisTemplate.hasKey(key);
}
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
}
}
JWT token校验与数据存储
@Component
public class JwtTokenFilter extends OncePerRequestFilter {
@Autowired
private RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (JwtUtils.verifyHeader(request)){
LoginUser user = JwtUtils.parseHeaderToken(request, UserInfo.class);
// 查询redis中token信息
LoginUser loginUser = redisCache.getHashObject(RedisCache.REDIS_KEY_LOGIN_TOKEN, user.getAccount(), LoginUser.class);
// 将登录信息配置到contextHolder中供下游业务使用
AmolUtils.getContext().setLoginUser(loginUser);
filterChain.doFilter(request, response);
} else {
throw new RuntimeException("User token invalid!request not allow。");
}
}
}
Web 工具类
public final class WebUtils {
private static final ThreadLocal<LoginContext> contextHolder = new ThreadLocal<>();
public void clearContext(){
contextHolder.remove();
}
public static void setContext(LoginContext context){
Assert.notNull(context, "Only non-null LoginContext instances are permitted.");
contextHolder.set(context);
}
public static LoginContext getContext(){
LoginContext ctx = (LoginContext)contextHolder.get();
if (ctx == null){
ctx = new LoginContext();
contextHolder.set(ctx);
}
return ctx;
}
/**
* @description 获取ContextHolder中的登录用户信息
* @return null
* @author PengHao
* @date 2023-08-08 11:26:35
*/
public static LoginUser getLoginUser(){
return getContext().getLoginUser();
}
/**
* @description 登录用户可以是doctorInfo或hospitalInfo,传入对应的类型即可获取登录对象信息
* @return null
* @author PengHao
* @date 2023-09-07 17:27:15
*/
public static <T> T getUserInfo(){
LoginUser user = getLoginUser();
if (Objects.isNull(user)){
return null;
}
return (T)getLoginUser();
}
public static HttpServletRequest getRequest(){
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
public static String getClientIp(){
return getRequest().getHeader(Constants.HEADER_X_Forwarded_For);
}
public static HttpSession getSession(){
return getRequest().getSession();
}
public static HttpServletResponse getResponse(){
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
}
public static WebApplicationContext getWebApplicationContext(){
return WebApplicationContextUtils.getWebApplicationContext(getRequest().getServletContext());
}
/**
* @description 获取容器中的Bean实例
* @param clazz
* @return null
* @author PengHao
* @date 2023-08-08 11:25:58
*/
public <T> T getBean(Class<T> clazz){
return getWebApplicationContext().getBean(clazz);
}
public Object getBean(String beanName){
return getWebApplicationContext().getBean(beanName);
}
/**
* @description 获取国际化资源信息
* @param request
* @return null
* @author PengHao
* @date 2023-08-08 11:25:30
*/
public static String getLocaleMsg(HttpServletRequest request, String code, Object ...args){
if (ArrayUtil.length(args) == 0){
return new RequestContext(request).getMessage(code);
} else {
return new RequestContext(request).getMessage(code, args);
}
}
public static String getLocalMsg(HttpServletRequest request, String code){
return getLocaleMsg(request, code, new Object[]{});
}
public static String getLocaleMsg(String code, Locale locale, Object ...args){
return getWebApplicationContext().getMessage(code, args, locale);
}
public static String getLocaleMsg(String code, Locale locale, String ifNull){
String msg = getLocaleMsg(code, locale, new Object[]{});
return StringUtils.isEmpty(msg) ? ifNull : msg;
}
}
SpringContext工具类
@Component
public class SpringContextUtils implements ApplicationContextAware{
private static ApplicationContext ac;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
ac = applicationContext;
}
public static <T> T getBean(Class<T> clazz){
return ac.getBean(clazz);
}
public static Object getBean(String beanName){
return ac.getBean(beanName);
}
public static <T> Map<String, T> getBeans(Class<T> clazz){
return ac.getBeansOfType(clazz);
}
}
日志配置
logging:
level:
com.kdaiyu: debug
file:
name: ./logs/kdaiyu-gateway.log
动态生成ReqeustMapping
public class AiStoreApplication implements InitializingBean
{
@Autowired
private AiStoreConfig aiStoreConfig;
public static void main(String[] args)
{
ConfigurableApplicationContext capp = SpringApplication.run(AiStoreApplication.class, args);
log.info(">> app start finish. active is {}.",capp.isActive());
}
@Override
public void afterPropertiesSet() throws Exception {
//获取RequestMappingHandlerMapping类后通过registerMapping方法注册reqestMapping
RequestMappingHandlerMapping bean = SpringUtils.getBean(RequestMappingHandlerMapping.class);
RequestMappingInfo mappingInfo = RequestMappingInfo.paths("/fuckSpring").methods(RequestMethod.GET).build();
try {
bean.registerMapping(mappingInfo, "aiCommonController", AiCommonController.class.getDeclaredMethod("fuckTest"));
log.debug("Dynamic controller register.");
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}