无法让 RestController 接受应用程序/八位字节流

问题描述 投票:0回答:2

我有一个带有休息控制器的 Spring Boot 应用程序,它必须在后端点接受二进制流并用它来执行操作。

所以我有:

    @PostMapping(path="/parse", consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    public String parse(RequestEntity<InputStream> entity) {
        return service.parse(entity.getBody());
    }

当我尝试使用 MockMvc 测试它时,我得到 org.springframework.web.HttpMediaTypeNotSupportedException。 我在日志中看到: 要求:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /parse
       Parameters = {}
          Headers = [Content-Type:"application/octet-stream;charset=UTF-8", Content-Length:"2449"]
             Body = ...skipped unreadable binary data...
    Session Attrs = {}

回应:

MockHttpServletResponse:
           Status = 415
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Accept:"application/json, application/*+json", 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 = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

我尝试添加显式标题:

    @PostMapping(path="/parse", consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE},
            headers = "Accept=application/octet-stream")

没有帮助。 测试电话是:

        mvc.perform(post("/parse")                       
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .content(bytes)
                ).andDo(print())
                .andExpect(status().isOk());

如何在不使用多部分形式的情况下使其工作?

java spring spring-mvc spring-restcontroller mockmvc
2个回答
1
投票

我分析了这个问题,发现问题出在这个方法上。

  @PostMapping(path="/parse", consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE})
    public String parse(RequestEntity<InputStream> entity) {
        return service.parse(entity.getBody());
    }

这里方法参数的类型是

RequestEntity<InputStream>
,应该是
HttpServletRequest

所以这是解决办法。

    @PostMapping(value = "/upload",
            consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public String demo(HttpServletRequest httpServletRequest) {

        try (ServletInputStream inputStream = httpServletRequest.getInputStream()) {
            new BufferedReader(new InputStreamReader(inputStream, UTF_8))
                    .lines().forEach(System.out::println);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return "Hello World";
    }

测试用例

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void shouldTestBinaryFileUpload() throws Exception {
        mockMvc
                .perform(MockMvcRequestBuilders
                        .post("/upload")
                        .content("Hello".getBytes())
                        .contentType(MediaType.APPLICATION_OCTET_STREAM))
                .andExpect(MockMvcResultMatchers
                        .status()
                        .isOk())
                .andExpect(MockMvcResultMatchers
                        .content()
                        .bytes("Hello World".getBytes()));
    }


0
投票

我遇到了同样的错误,并通过添加 mvc 配置中缺少的 ocet 流转换器来修复它。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer { 
  @Override 
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters){
    convertes.add(new ByteArrayHttpMessageConverter());
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.