【问题标题】:"Could not find acceptable representation" when testing spring download link with MockMvc使用 MockMvc 测试 spring 下载链接时“找不到可接受的表示”
【发布时间】:2019-06-21 09:15:24
【问题描述】:

我有一个控制器应该允许下载具有任意内容类型的文件:

@GetMapping(value="/download/{directory}/{name}",
            consumes=MediaType.ALL_VALUE)
@Timed
public ResponseEntity<byte[]> downloadFile(@PathVariable String directory,
                                           @PathVariable String name) {
    log.debug("REST request to download File : {}/{}", directory, name);

    byte[] content = "it works".getBytes();
    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_TYPE, "text/plain");
    return new ResponseEntity<>(content, headers, HttpStatus.OK);
}

我想在这样的单元测试中进行测试:

...
private MockMvc restFileMockMvc;

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);

    final FileResource fileResource = new FileResource(fileService);
    this.restFileMockMvc = MockMvcBuilders.standaloneSetup(fileResource)
        .setCustomArgumentResolvers(pageableArgumentResolver)
        .setControllerAdvice(exceptionTranslator)
        .setConversionService(createFormattingConversionService())
        .setMessageConverters(jacksonMessageConverter)
        .setValidator(validator).build();
}

@Test
@Transactional
public void downloadFile() throws Exception {
    String url = "/api/download/it/works.txt";
    restFileMockMvc.perform(get(url).header(HttpHeaders.ACCEPT, "*/*"))
                   .andDo(MockMvcResultHandlers.print()) // Debugging only!
                   .andExpect(status().isOk());
}

但显然,内容类型存在问题。接受标头。 MockMvcResultHandlers.print() 产生以下内容:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /api/download/DIRDIR/NAMENAME
       Parameters = {}
          Headers = {Accept=[*/*]}
             Body = <no character encoding set>
    Session Attrs = {}

Handler:
             Type = com.example.storage.web.rest.FileResource
           Method = public org.springframework.http.ResponseEntity<byte[]> com.example.storage.web.rest.FileResource.downloadFile(java.lang.String,java.lang.String)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.web.HttpMediaTypeNotAcceptableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 406
    Error message = null
          Headers = {Content-Type=[application/problem+json]}
     Content type = application/problem+json
             Body = {"type":"https://www.jhipster.tech/problem/problem-with-message","title":"Not Acceptable","status":406,"detail":"Could not find acceptable representation","path":"/api/download/DIRDIR/NAMENAME","message":"error.http.406"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

看起来请求是使用Accept: */* 发送的。 Spring 抱怨什么?

【问题讨论】:

  • 您没有Content-Type 标头,只有Accept 标头。
  • @M. Deinum Content-Type 是响应头,Accept 是请求头。
  • Content-Type 既是请求又是响应。
  • 但这是一个获取请求。它没有身体。
  • 它仍然需要标题。从@RequstMapping 中删除consumes 部分。

标签: spring spring-mvc


【解决方案1】:

我已经在使用@SpringJUnitWebConfig(...) 并将@EnableWebMvc 注释添加到我导入的配置中。这似乎添加了所有必要的转换器。例如

@SpringJUnitWebConfig(MyTestConfig.class)
class MyTest {

  @Inject
  private WebApplicationContext wac;

  private MockMvc mockMvc;
  ...
}

@EnableWebMvc
class MyTestConfig {
  @Bean
  ...
}

【讨论】:

    【解决方案2】:

    这可能是您在测试用例中使用的消息转换器的问题。我也遇到了类似的问题,并通过在 messageConverter 中为我的 mockMvc 传递附加参数来解决它

     this.restMockMvc = MockMvcBuilders.standaloneSetup(testResource)
            .setCustomArgumentResolvers(pageableArgumentResolver)
            .setControllerAdvice(exceptionTranslator)
            .setMessageConverters(jacksonMessageConverter,new 
           ByteArrayHttpMessageConverter()).build();
    

    您需要为 MockMVC 重载消息转换器属性。欲了解更多信息,relevant question

    【讨论】:

    • 添加new ByteArrayHttpMessageConverter() 成功了!非常感谢!
    • 您的回答对我有帮助!如果返回ResponseEntity,则需要在messageConverters中添加ResourceHttpMessageConverter。
    猜你喜欢
    • 2019-04-13
    • 2016-09-28
    • 2022-10-20
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2015-05-08
    • 2019-01-23
    相关资源
    最近更新 更多