Spring Boot:处理SizeLimitExceededException总是给出" SocketException:软件导致连接中止:recv失败"在RestTemplate中

时间:2018-03-06 11:40:19

标签: java spring spring-boot resttemplate spring-restcontroller

我使用的是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;
    }
}

0 个答案:

没有答案