簡體   English   中英

HttpMediaTypeNotAcceptableException:在exceptionhandler中找不到可接受的表示形式

[英]HttpMediaTypeNotAcceptableException: Could not find acceptable representation in exceptionhandler

我的控制器(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測試完美無瑕

編輯這是因為擴展.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測試中也失敗了):

ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public java.util.Map<java.lang.String, java.lang.String> nl.krocket.ocr.web.controller.ExceptionController.handleResourceNotFoundException(nl.krocket.ocr.web.backing.ResourceNotFoundException) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation

我在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測試有效?

您需要決定Spring應如何確定響應的媒體類型。 這可以通過以下幾種方式完成:

  • 路徑擴展(例如/image.jpg)
  • URL參數(例如?格式= jpg)
  • HTTP Accept標頭(例如,Accept:image / jpg)

默認情況下,Spring查看擴展而不是Accept標頭。 如果您實現擴展WebMvcConfigurerAdapter@Configuration類(或者因為Spring 5.0只是實現WebMvcConfigurer則可以更改此行為。您可以覆蓋configureContentNegotiation(ContentNegotiationConfigurer configurer)並根據需要配置ContentNegotiationConfigurer ,例如通過調用

ContentNegotiationConfigurer#favorParameter
ContentNegotiationConfigurer#favorPathExtension

如果將兩者都設置為false ,那么Spring將查看Accept標頭。 由於您的客戶端可以說Accept: image/*,application/json並處理它們,因此Spring應該能夠返回圖像或錯誤JSON。

有關更多信息和示例,請參閱有關內容協商的Spring教程

請注意您的HTTP Accept標頭。 例如,如果您的控制器生成“application / octet-stream”(作為響應),您的Accept標頭不應該是“application / json”(在請求中):

@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void download(HttpServletResponse response) {}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM