Skip to content

Springboot常用工具集配置

1117字约4分钟

springbootjava

2024-09-19

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);
        }
    }
}

陕ICP备2021014644号-1