Bug记录——搬用、挪用、使用、借鉴、学习别人SpringBoot工程的二三事
一、前端明明返回了token,检查前端没问题了(就是axios响应拦截有数据,then没数据)
找了半天前端的问题,最后发现,原因是后端ResultHandler
的扫包问题
Result实体类
package com.example.demo.entity;
import lombok.Data;
/**
* 统一返回的数据格式
* @author sxj
* @param <T>
*/
@Data
public class Result<T> {
private Integer code; // 状态码
private String message; // 状态描述信息
private T data; // 定义为范型
}
aspect包--ResultHandler
package com.example.demo.aspect;
import com.example.demo.entity.Result;
import com.example.demo.exception.ErrorCode;
import com.example.demo.util.ResultUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
/**
* 按照统一格式返回值
* @author sxj
*/
@ControllerAdvice(basePackages = "com.example.demo.controller")
public class ResultHandler implements ResponseBodyAdvice {
private ThreadLocal<ObjectMapper> mapperThreadLocal = ThreadLocal.withInitial(ObjectMapper::new);
private static final Class[] annos = {
RequestMapping.class,
GetMapping.class,
PostMapping.class,
DeleteMapping.class,
PutMapping.class
};
/**
* 对所有RestController的接口方法进行拦截
*/
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
AnnotatedElement element = returnType.getAnnotatedElement();
return Arrays.stream(annos).anyMatch(anno -> anno.isAnnotation() && element.isAnnotationPresent(anno));
}
@Override
public Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
Object out;
ObjectMapper mapper = mapperThreadLocal.get();
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
if(body instanceof Result){
out = body;
}
else if (body instanceof ErrorCode){
ErrorCode errorCode = (ErrorCode) body;
out = ResultUtil.error(errorCode.getCode(),errorCode.getMessage());
}
else if (body instanceof String){
Result result = ResultUtil.success(body);
try {
//因为是String类型,我们要返回Json字符串,否则SpringBoot框架会转换出错
out = mapper.writeValueAsString(result);
} catch (JsonProcessingException e) {
out = ResultUtil.error(ErrorCode.JSON_PARSE_ERROR);
}
}
else{
out = ResultUtil.success(body);
}
return out;
}
}
总结:每次使用别人的工程时,可以使用idea的
edit
-->find
-->replace in files
进行包名替换
二、多看看xml文件吧
使用自己的数据库时,改别人的xml还是要改很多的,一旦不小心就会报错,
例如:
在通用结果映射查询(BaseResultMap)里面明明将user_id映射成了userId
但是仍然错误的使用了user_id
<collection column="{userId = user_id}"/>
点击查看代码
<resultMap id="UserVoResult" extends="BaseResultMap" type="com.example.demo.vo.UserVo">
<collection property="roles" column="{userId = userId}" ofType="com.example.demo.entity.Role" select="com.example.demo.mapper.RoleMapper.listByUserId"/>
</resultMap>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构