400将带有Spring RestTemplate的字节[]上载到SpringMVC rest端点时请求错误
我正在尝试将包含映像的字节[]作为多部分文件上载到我的Spring rest服务(在Spring Boot中运行,顺便说一句),我的客户端正在运行Spring RestTemplate,并且收到HttpClientErrorException:400错误请求 我的端点: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
@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);
}