복붙노트

[SPRING] HttpMediaTypeNotAcceptableException : 예외 처리기에서 허용되는 표현을 찾을 수 없습니다.

SPRING

HttpMediaTypeNotAcceptableException : 예외 처리기에서 허용되는 표현을 찾을 수 없습니다.

내 컨트롤러 (Spring 4.1)에는 다음 이미지 다운로드 방법이 있습니다.

@RequestMapping(value = "/get/image/{id}/{fileName}", method=RequestMethod.GET)
public @ResponseBody byte[] showImageOnId(@PathVariable("id") String id, @PathVariable("fileName") String fileName) {
    setContentType(fileName); //sets contenttype based on extention of file
    return getImage(id, fileName);
}

다음 ControllerAdvice 메서드는 존재하지 않는 파일을 처리하고 json 오류 응답을 반환해야합니다.

@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public @ResponseBody Map<String, String> handleResourceNotFoundException(ResourceNotFoundException e) {
    Map<String, String> errorMap = new HashMap<String, String>();
    errorMap.put("error", e.getMessage());
    return errorMap;
}

내 JUnit 테스트가 완벽하게 작동합니다.

(EDIT 이것은 확장 기능 때문입니다 .bla : 이것은 appserver에서도 작동합니다) :

@Test
public void testResourceNotFound() throws Exception {
    String fileName = "bla.bla";
      mvc.perform(MockMvcRequestBuilders.get("/get/image/bla/" + fileName)
            .with(httpBasic("test", "test")))
            .andDo(print())
            .andExpect(jsonPath("$error").value(Matchers.startsWith("Resource not found")))
            .andExpect(status().is(404));
}

다음과 같은 결과를 얻습니다 :

MockHttpServletResponse:
          Status = 404
   Error message = null
         Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Content-Type=[application/json]}
    Content type = application/json
            Body = {"error":"Resource not found: bla/bla.bla"}
   Forwarded URL = null
  Redirected URL = null
         Cookies = []

그러나 내 appserver에서 기존 이미지가 아닌 다운로드하려고하면 다음 오류 메시지가 나타납니다.

(이것은 .jpg 확장자로 인해 편집됩니다. 확장자가 .jpg 인 JUnit 테스트에서도 실패합니다.)

오류 org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - @ExceptionHandler 메서드를 호출하지 못했습니다 : public java.util.Map nl.krocket.ocr.web .controller.ExceptionController.handleResourceNotFoundException (nl.krocket.ocr.web.backing.ResourceNotFoundException) org.springframework.web.HttpMediaTypeNotAcceptableException : 받아 들일 수있는 표현을 찾을 수 없습니다.

mvc 구성에서 다음과 같이 messageconverters를 구성했습니다.

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(mappingJackson2HttpMessageConverter());
    converters.add(byteArrayHttpMessageConverter());
}

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    //objectMapper.registerModule(new JSR310Module());
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(objectMapper);
    converter.setSupportedMediaTypes(getJsonMediaTypes());
    return converter;
}

@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
    ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
    arrayHttpMessageConverter.setSupportedMediaTypes(getImageMediaTypes());
    return arrayHttpMessageConverter;
}

나는 무엇을 놓치고 있습니까? 그리고 JUnit 테스트가 작동하는 이유는 무엇입니까?

해결법

  1. ==============================

    1.Spring이 응답의 미디어 유형을 결정하는 방법을 결정해야합니다. 이것은 여러 가지 방법으로 수행 할 수 있습니다.

    Spring이 응답의 미디어 유형을 결정하는 방법을 결정해야합니다. 이것은 여러 가지 방법으로 수행 할 수 있습니다.

    기본적으로 Spring은 Accept 헤더 대신 확장을 살펴 본다. WebMvcConfigurerAdapter를 확장하는 @Configuration 클래스를 구현하면이 동작을 변경할 수 있습니다. 여기서 configureContentNegotiation (ContentNegotiationConfigurer 구성 자)을 무시하고 필요에 맞게 구성자를 구성 할 수 있습니다 (예 : 전화 걸기

    ContentNegotiationConfigurer#favorParameter
    ContentNegotiationConfigurer#favorPathExtension
    

    둘 다 false로 설정하면 Spring은 Accept 헤더를 볼 것이다. 클라이언트가 Accept : image / *, application / json을 처리하고 둘 다 처리 할 수 ​​있으므로 Spring은 이미지 또는 JSON 오류를 반환 할 수 있어야합니다.

    더 자세한 정보와 예제는 컨텐츠 협상에 대한 Spring 튜토리얼을 참조하십시오.

  2. ==============================

    2.HTTP 수락 헤더에주의하십시오. 예를 들어 컨트롤러가 "application / octet-stream"(응답으로)을 생성하면 Accept 헤더는 "application / json"이되어서는 안됩니다 (요청시).

    HTTP 수락 헤더에주의하십시오. 예를 들어 컨트롤러가 "application / octet-stream"(응답으로)을 생성하면 Accept 헤더는 "application / json"이되어서는 안됩니다 (요청시).

    @GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void download(HttpServletResponse response) {}
    
  3. from https://stackoverflow.com/questions/32351142/httpmediatypenotacceptableexception-could-not-find-acceptable-representation-in by cc-by-sa and MIT license