fix(controller): 修复文件上传参数绑定与异常处理
- FileController:把 @RequestParam 改成 @RequestPart 并去掉多余注解 - GlobalExceptionHandler:新增 MissingServletRequestPartException 拦截,返回 FILE_IS_EMPTY 错误码 - RequestBodyCacheFilter:跳过 multipart 请求,避免文件上传被缓存过滤器破坏 - UserServiceImpl:修正更新语句为 updateById,防止字段丢失
This commit is contained in:
@@ -27,8 +27,7 @@ public class FileController {
|
|||||||
|
|
||||||
@PostMapping("/upload")
|
@PostMapping("/upload")
|
||||||
@Operation(summary = "上传文件", description = "上传文件接口")
|
@Operation(summary = "上传文件", description = "上传文件接口")
|
||||||
@Parameter(name = "file",required = true,description = "上传的文件")
|
public BaseResponse<String> upload(@RequestPart("file") MultipartFile file){
|
||||||
public BaseResponse<String> upload(@RequestParam("file") MultipartFile file){
|
|
||||||
String fileUrl = fileService.upload(file);
|
String fileUrl = fileService.upload(file);
|
||||||
return ResultUtils.success(fileUrl);
|
return ResultUtils.success(fileUrl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局异常处理器
|
* 全局异常处理器
|
||||||
@@ -25,6 +26,20 @@ public class GlobalExceptionHandler {
|
|||||||
this.i18nService = i18nService;
|
this.i18nService = i18nService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(MissingServletRequestPartException.class)
|
||||||
|
public BaseResponse<?> missingServletRequestPartExceptionHandler(MissingServletRequestPartException e, HttpServletRequest request) {
|
||||||
|
log.error("missingServletRequestPartException: " + e.getMessage(), e);
|
||||||
|
|
||||||
|
String acceptLanguage = request.getHeader("Accept-Language");
|
||||||
|
String errorMessage = i18nService.getMessageWithAcceptLanguage(String.valueOf(ErrorCode.FILE_IS_EMPTY.getCode()), acceptLanguage);
|
||||||
|
|
||||||
|
if (errorMessage == null) {
|
||||||
|
errorMessage = ErrorCode.FILE_IS_EMPTY.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultUtils.error(ErrorCode.FILE_IS_EMPTY.getCode(), errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
@ExceptionHandler(BusinessException.class)
|
@ExceptionHandler(BusinessException.class)
|
||||||
public BaseResponse<?> businessExceptionHandler(BusinessException e, HttpServletRequest request) {
|
public BaseResponse<?> businessExceptionHandler(BusinessException e, HttpServletRequest request) {
|
||||||
log.error("businessException: " + e.getMessage(), e);
|
log.error("businessException: " + e.getMessage(), e);
|
||||||
|
|||||||
@@ -18,15 +18,27 @@ public class RequestBodyCacheFilter extends OncePerRequestFilter {
|
|||||||
FilterChain filterChain)
|
FilterChain filterChain)
|
||||||
throws ServletException, IOException {
|
throws ServletException, IOException {
|
||||||
|
|
||||||
// 只缓存一次
|
// 获取请求的内容类型
|
||||||
|
String contentType = request.getContentType();
|
||||||
|
|
||||||
|
// 跳过 multipart 请求,避免破坏文件上传功能
|
||||||
|
if (contentType != null && contentType.toLowerCase().startsWith("multipart/")) {
|
||||||
|
// 对于文件上传请求,直接放行,不进行请求体缓存
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否已经进行过请求体缓存,避免重复缓存
|
||||||
if (!(request instanceof CachedBodyHttpServletRequest)) {
|
if (!(request instanceof CachedBodyHttpServletRequest)) {
|
||||||
|
// 创建缓存请求对象,包装原始请求以支持多次读取请求体
|
||||||
CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(request);
|
CachedBodyHttpServletRequest cachedRequest = new CachedBodyHttpServletRequest(request);
|
||||||
|
|
||||||
|
// 使用缓存的请求对象继续执行过滤器链
|
||||||
filterChain.doFilter(cachedRequest, response);
|
filterChain.doFilter(cachedRequest, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果已经是缓存过的请求,则直接执行过滤器链
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -191,7 +191,8 @@ public class UserServiceImpl extends ServiceImpl<KeyboardUserMapper, KeyboardUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyboardUser keyboardUser = BeanUtil.copyProperties(keyboardUserReq, KeyboardUser.class);
|
KeyboardUser keyboardUser = BeanUtil.copyProperties(keyboardUserReq, KeyboardUser.class);
|
||||||
Integer i = keyboardUserMapper.updateByuid(keyboardUser);
|
keyboardUser.setId(loginIdAsLong);
|
||||||
|
int i = keyboardUserMapper.updateById(keyboardUser);
|
||||||
if (i <=0 ) {
|
if (i <=0 ) {
|
||||||
throw new BusinessException(ErrorCode.USER_INFO_UPDATE_FAILED);
|
throw new BusinessException(ErrorCode.USER_INFO_UPDATE_FAILED);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user