400将带有Spring RestTemplate的字节[]上载到SpringMVC rest端点时请求错误

400将带有Spring RestTemplate的字节[]上载到SpringMVC rest端点时请求错误,spring,spring-boot,resttemplate,Spring,Spring Boot,Resttemplate,我正在尝试将包含映像的字节[]作为多部分文件上载到我的Spring rest服务(在Spring Boot中运行,顺便说一句),我的客户端正在运行Spring RestTemplate,并且收到HttpClientErrorException:400错误请求 我的端点: @RequestMapping(value="/scale/{percent}", method= RequestMethod.POST) public ResponseEntity scaleImage(@PathVariab

我正在尝试将包含映像的字节[]作为多部分文件上载到我的Spring rest服务(在Spring Boot中运行,顺便说一句),我的客户端正在运行Spring RestTemplate,并且收到HttpClientErrorException:400错误请求

我的端点:

@RequestMapping(value="/scale/{percent}", method= RequestMethod.POST)
public ResponseEntity scaleImage(@PathVariable("percent") float percent,
                                        @RequestParam("file") MultipartFile file) {

    try {
        if (!file.isEmpty()) {
            byte [] result = transformService.scaleImage(percent, file.getBytes());
            return getResponseEntityFromBytes(result);
        } else {
            return generateBadRequestError();
        }
    } catch (Exception e) {
        if (e instanceof InvalidOperationParameterException) {
            // TODO - populate message with bad parameters
            LOGGER.log(Level.FINE, "Invalid Parameters: ");
            return generateBadRequestError();
        } else {
            LOGGER.log(Level.SEVERE, "Exception caught: " + e.getMessage(), e);
            return generateServerError(e.getMessage());
        }
    }
}
我的Spring RestTemplate客户端:

public void scaleImage(byte[] image, float percent) throws Exception {
    String url = "http://localhost:8080/scale/" + percent;
    this.testNumberThreads=10;
    this.testNumberThreads=10;

    MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<>();
    mvm.add("file", image);
    TransformedResponse r = doPost(url, mvm);
}

private TransformedResponse doPost(String url, MultiValueMap<String, Object> mvm) {
    RestTemplate restTemplate = new RestTemplate();
    TransformedResponse xr = null;
    try {
        xr = restTemplate.postForObject(url, mvm, TransformedResponse.class);
    } catch (RestClientException e) {
        e.printStackTrace();
    }
    return xr;
}
下面是我在客户机中看到的一个例外(还没有任何东西击中服务器):


为什么此请求无法正确发布?

请尝试以下操作,而不是尝试将
多部分文件作为请求参数传入:

@RequestMapping(value="/scale/{percent}", method= RequestMethod.POST)
public ResponseEntity scaleImage(@PathVariable("percent") float percent,
        MultipartHttpServletRequest request) {
    Iterator<String> fileNames = request.getFileNames();
    MultipartFile uploadedFile = request.getFile(fileNames.next());
    String fileName = uploadedFile.getName();
@RequestMapping(value=“/scale/{percent}”,method=RequestMethod.POST)
公共响应级别图像(@PathVariable(“百分比”)浮动百分比,
MultipartTTPServletRequest(请求){
迭代器文件名=request.getFileNames();
MultipartFile uploadedFile=request.getFile(fileNames.next());
字符串文件名=uploadedFile.getName();
这是我能够真正让我的多部分文件被接受的唯一方法


如果您仍然从这个过程中获得一个空文件,那么这一定与您发布数据的方式有关。

首先,在使用Spring时,请确保您在servlet上下文中定义了正确的
多部分文件
解析器:

<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="52428800"/>
    <property name="maxInMemorySize" value="52428800"/>
</bean>
最后,在控制器中处理文件上载

@RequestMapping(value="/path", method= RequestMethod.POST)
public StringscaleImage(@RequestParam("file") MultipartFile file) {
    //....
}
请记住,只有HTML5才支持异步文件上载,而其他的则需要使用一些变通方法(如flash或iFrame)

如果您仍然面临
400
错误,请将此记录器(或类似记录器,取决于日志框架)添加到日志服务中:



它应该输出在请求处理过程中引发的异常,而不是原始字节数组。我发现了我的问题。我需要将
抽象资源
(在本例中是
ByteArrayResource
)添加到我的
多值映射
。下面是修复该问题的代码:

public void scaleImage(byte[] image, float percent) throws Exception {
    String url = "http://localhost:8080/scale/" + percent;

    final byte[] rawBytes = image.clone();

    MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<>();
    ByteArrayResource bar = new ByteArrayResource(rawBytes) {
        @Override
        public String getFilename() {
            return "Test-"+rawBytes.length + ".jpg";
        }
    };

    mvm.add("file", bar);
    TransformedResponse r = doPost(url, mvm);
}
public void scaleImage(字节[]图像,浮点百分比)引发异常{
字符串url=”http://localhost:8080/scale/“+百分比;
最终字节[]rawBytes=image.clone();
MultiValueMap mvm=新链接的MultiValueMap();
ByteArrayResource bar=新的ByteArrayResource(rawBytes){
@凌驾
公共字符串getFilename(){
返回“Test-”+rawBytes.length+“.jpg”;
}
};
添加(“文件”,条形图);
TransformedResponse r=doPost(url,mvm);
}

是以
/
为前缀的
百分比
值吗?您对url的调用如下:
字符串url=”http://localhost:8080/scale"+percent;
。此外,您是否在servlet配置中启用了对多部分文件的支持?这很有帮助。服务器接受了请求,但我得到了:
java.util.NoSuchElementException:null位于java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:396)位于java.util.LinkedHashMap$KeyIterator.nextsun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)上
看起来它需要一个文件名我的spring引导配置中有一个解析器-它解决了另一个未找到解析器的问题,但在遇到400错误之前已经解决了:`@Bean public CommonsMultipartResolver multipartResolver(){System.out.println(==>>>>>多部分解析器调用:“);CommonsMultipartResolver multipartResolver=新的CommonsMultipartResolver();multipartResolver.setMaxUploadSize(5000000);返回multipartResolver;}`为什么需要克隆?
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${your.spring.version}</version>
</dependency>
<form method="post" action="upload.form" enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit"/>
</form>
@RequestMapping(value="/path", method= RequestMethod.POST)
public StringscaleImage(@RequestParam("file") MultipartFile file) {
    //....
}
<appender name="console" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <param name="threshold" value="TRACE"/>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p [%c] %m%n"/>
    </layout>
</appender>

<logger name="org.springframework.web.method.HandlerMethod">
    <level value="TRACE"/>
</logger>

<root>
    <priority value="info"/>
    <appender-ref ref="console"/>
</root>
public void scaleImage(byte[] image, float percent) throws Exception {
    String url = "http://localhost:8080/scale/" + percent;

    final byte[] rawBytes = image.clone();

    MultiValueMap<String, Object> mvm = new LinkedMultiValueMap<>();
    ByteArrayResource bar = new ByteArrayResource(rawBytes) {
        @Override
        public String getFilename() {
            return "Test-"+rawBytes.length + ".jpg";
        }
    };

    mvm.add("file", bar);
    TransformedResponse r = doPost(url, mvm);
}