我使用的是Spring boot 1.5.10。我有一个处理文件上传的RestController,我使用RestTemplate从另一个进程调用。
当我尝试上传的文件太大时,Tomcat会触发org.apache.tomcat.util.http.fileupload.FileUploadBase.SizeLimitExceededException(如预期的那样)。我希望通过返回自定义HTTP响应很好地处理它,但到目前为止,我的尝试似乎都没有任何关系,因为restTemplate.exchange总是抛出以下异常:
org.springframework.web.client.ResourceAccessException:I / O错误 POST请求" http://127.0.0.1:8080/api/upload":软件 导致连接中止:recv失败;嵌套异常是 java.net.SocketException:软件导致连接中止:recv 失败
到目前为止我已尝试过:
我错过了什么?为什么我的处理程序的响应被忽略了?
我在Mac上尝试了ExceptionHandler方法,它按预期工作。这可能是特定于Windows的吗?
这是我的一些代码(仅限有效位):
上传控制器方法:
@PostMapping("/upload")
public ResponseEntity<?> uploadFile(
@RequestParam("file") MultipartFile file
) throws IOException {
// do something with the file
return new ResponseEntity<>("Successfully uploaded '" + file.getOriginalFilename() +"'",
new HttpHeaders(), HttpStatus.OK);
}
RestTemplate调用:
RestTemplate restTemplate = new RestTemplate();
URL url = new URL("http", this.targetHostname, this.targetPort, "/upload");
// build request
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
map.add("file", new PathResource(path));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(map, headers);
// perform HTTP request
ResponseEntity<String> result;
try {
result = restTemplate.exchange(
url.toURI(),
HttpMethod.POST,
requestEntity,
String.class);
} catch (RestClientException e) {
log.error("Exception during file upload: ", e);
return;
}
log.debug("Result of upload: " + result);
尝试使用ExceptionHandler:
@ControllerAdvice
public class RestResponseEntityExceptionHandler {
@ExceptionHandler(MultipartException.class)
@ResponseBody
ResponseEntity<?> handleMultipartException(HttpServletRequest request, Throwable ex) throws Throwable {
Throwable cause = ex.getCause();
if (cause instanceof IllegalStateException) {
Throwable cause2 = cause.getCause();
if (cause2 instanceof FileUploadBase.SizeLimitExceededException) {
return new ResponseEntity<>(cause2.toString(), HttpStatus.PAYLOAD_TOO_LARGE);
}
}
throw ex;
}
}
尝试使用ErrorHandler:
@RestController
public class RestErrorController implements ErrorController {
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public String error() {
return "Some error message";
}
@Override
public String getErrorPath() {
return PATH;
}
}