I am trying to upload an image to a servlet, but every once and a while during automated testing, it silently fails.
Do you guys know what would cause this?
Here is the code on the server:
#ResponseBody
#RequestMapping(method = RequestMethod.POST)
public String upload(HttpServletRequest request) throws Exception {
BufferedImage image = null;
#SuppressWarnings("unchecked")
List<FileItem> items = new ServletFileUpload(
new DiskFileItemFactory()).parseRequest(request);
Logger.log(LogLevel.INFO, "Upload contains " + items.size()
+ " items.");
int i = 0;
for (FileItem item : items) {
Logger.log(LogLevel.INFO, "\tItem " + (i++) + ". Name:\t"
+ item.getName() + ", Type:\t" + item.getContentType());
// File is of type "file"
if (!item.isFormField()) {
InputStream inputStream = null;
try {
inputStream = item.getInputStream();
if (inputStream.available() == 0) {
Logger.log(LogLevel.WARN,
"Item shows file type, but no bytes are available");
}
image = ImageIO.read(inputStream);
if (image != null) {
break;
}
} catch (Exception e) {
Logger.log(LogLevel.ERROR,
"There was an error reading the image. "
+ ExceptionUtils.getFullStackTrace(e));
throw new Exception("image provided is not a valid image");
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
}
}
}
if (image == null) {
Logger.log(LogLevel.ERROR, "Image was supposedly read correctly, but was null afterwards");
throw new Exception("Image provided could not be read");
}
//do stuff with image
...
}
Here is the test:
public void testImageUpload throws Exception {
HttpPost httppost = new HttpPost("path/to/endpoint");
File file=new File(imgLoc);
FileBody bin = new FileBody(file);
StringBody comment = new StringBody("Filename: " + file);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("upload-file", bin);
reqEntity.addPart("comment", comment);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Connection","Keep-Alive");
httppost.setEntity(reqEntity);
HttpResponse response =testClient.getClient().execute(httppost);
imgResponse=response.getStatusLine().toString();
System.out.println(imgResponse);
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = reader.readLine()) != null){
output = output + " " +line;}
System.out.println("Image Response: "+output);
}
Here is the output from the server when it fails:
2013/10/02 05-53-32,287::LOG:INFO[com.example#upload:L130 -- Upload contains 2 items.]
2013/10/02 05-53-32,288::LOG:INFO[com.example#upload:L133 -- Item 0. Name: Dog.jpg, Type: application/octet-stream]
2013/10/02 05-53-32,288::LOG:WARN[com.example#upload:L140 -- Item shows file type, but no bytes are available]
2013/10/02 05-53-32,289::LOG:INFO[com.example#upload:L133 -- Item 1. Name: null, Type: text/plain; charset=ISO-8859-1]
2013/10/02 05-53-32,290::LOG:ERROR[com.example#upload:L159 -- Image was supposedly read correctly, but was null afterwards]
We catch the exception from the image upload and send back a response code of 422 back to the client, so on the test, we get imgResponse==422 which is a failure case.
Note: this only happens sometimes you run the test.
Here is step by step configuration for file uploading by using Apache Commons FileUpload:
1. Add dependency jars for the following component. Here is the maven dependencies:
pom.xml
<dependencies>
<!-- Spring 3 MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
<!-- Apache Commons file upload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- Apache Commons IO -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- JSTL for c: tag -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
If you are not using maven then download respective jar from the maven repository online.
2. Create a FileUploadForm model
FileUploadForm.java
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class FileUploadForm {
private List<MultipartFile> files;
//Getter and setter methods
}
3. Add resolver to MVC config file
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
4. Write FileUploadController
FileUploadController.java
#Controller
public class FileUploadController {
#RequestMapping(value = "/show", method = RequestMethod.GET)
public String displayForm() {
return "file_upload_form";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(
#ModelAttribute("uploadForm") FileUploadForm uploadForm,
Model map) {
List<MultipartFile> files = uploadForm.getFiles();
List<String> fileNames = new ArrayList<String>();
if(null != files && files.size() > 0) {
for (MultipartFile multipartFile : files) {
String fileName = multipartFile.getOriginalFilename();
fileNames.add(fileName);
//Handle file content - multipartFile.getInputStream()
}
}
map.addAttribute("files", fileNames);
return "file_upload_success";
}
}
5. Write jsp views
file_upload_form.jsp
<html>
<head>
<title>Spring MVC Multiple File Upload</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
//add more file components if Add is clicked
$('#addFile').click(function() {
var fileIndex = $('#fileTable tr').children().length - 1;
$('#fileTable').append(
'<tr><td>'+
' <input type="file" name="files['+ fileIndex +']" />'+
'</td></tr>');
});
});
</script>
</head>
<body>
<h1>Spring Multiple File Upload example</h1>
<form method="post" action="save.html"
**enctype="multipart/form-data"**>
<p>Select files to upload. Press Add button to add more file inputs.</p>
<input id="addFile" type="button" value="Add File" />
<table id="fileTable">
<tr>
<td><input name="files[0]" type="file" /></td>
</tr>
<tr>
<td><input name="files[1]" type="file" /></td>
</tr>
</table>
<br/><input type="submit" value="Upload" />
</form>
</body>
</html>
Reference: http://docs.spring.io/spring/docs/3.2.4.RELEASE/spring-framework-reference/html/mvc.html#mvc-multipart
It seems your content type is application/octet-stream. Please add the below Header in your request and give a try
("Content-Type", "multipart/form-data");
You are using InputStream#available. As the documentation states this is the number of bytes that can be read from the stream without blocking. Now, how many bytes are available from the TCP input stream depends on the size of the the packets and how your request is sliced amongst them (and a lot more other factors).
If your intention is to always read the stream in full, forget the available() method, just read it out until the end of stream and you should be fine.
I've come across this before under two conditions. Once was when I ran low on disk space and the other was when I was doing a bit of load test.
If you take a look at the How it works page, you can make the tool dump items to disk or keep them in memory. Under one case I filled up the drive during testing and the other I was keeping items in memory but the load blew my memory limit.
How do you have it set up? How big is the image you are using to test? How many times do yo upload it during your tests? With this info, I should be able to help a bit more.
This code is used on my site currently, works like a charm:
package com.example;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
#Controller
#RequestMapping("/api/media")
public class ImageRestService {
private static final Logger LOG = LoggerFactory.getLogger(ImageRestService.class);
#RequestMapping(value = "/uploadtemp", method = RequestMethod.POST)
public String upload(#RequestParam(value = "image") MultipartFile image) {
try {
BufferedImage bufferedImage = ImageIO.read(image.getInputStream());
// process image here
} catch (IOException e) {
LOG.error("failed to process image", e);
return "failure/view/name";
}
return "success/view/name";
}
}
Maybe the order of the items list is not fixed (timing dependent?). Your code
if (image != null) {
break;
}
quits the loop instead of trying the next parts. In the comments you state we iterate through the files until we can parse one, which should read
if (image != null) {
continue;
}
then.
Related
I'm trying to build a simple Webscript Endpoint in Alfresco that gets a pdf using a Java Webscript controller. We eventually want to expand this endpoint to take multiple pdfs and do some manipulation, but for right now we are just trying to read in and save 1 pdf.
The problem is the resulting InputStream is empty. This is despite it working just fine for xml files.
This is our uploadpdf.get.desc
<webscript>
<shortname>Upload PDFs</shortname>
<description>Upload PDFs</description>
<url>/uploadpdf</url>
<authentication>user</authentication>
<format default="html"></format>
</webscript>
This is our uploadpdf.get.html.ftl
<html>
<body>
<form action="${url.service}" method="post" enctype="multipart/form-data">
PDF1: <input type="file" name="pdf1"><br>
XML1: <input type="file" name="xml1"><br>
<input type="submit" name="submit" value="Upload">
</form>
</body>
</html>
This is our uploadpdf.post.dec
<webscript>
<shortname>Upload PDFs</shortname>
<description>Upload PDFs</description>
<url>/uploadpdf</url>
<authentication>user</authentication>
<format default="json"></format>
</webscript>
This is our uploadpdf.post.json.ftl (currently just returning a test string)
${newFile}
This is our Webscript-context.xml
<?xml version='1.0' encoding='UTF-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="webscript.alfresco.tutorials.helloworld.get"
class="com.test.platformsample.HelloWorldWebScript"
parent="webscript">
</bean>
<bean id="webscript.uploadpdf.get"
class="com.test.UploadPdfWebScript"
parent="webscript">
</bean>
<bean id="webscript.uploadpdf.post"
class="com.test.UploadPdfWebScript"
parent="webscript">
</bean>
</beans>
And this is our UploadPdfWebscript.java (notice for testing purposes we are using org.springframework.extensions.webscripts.servlet.FormData;
This is to easily get the file. The code then saves the file to the local docker container. The problem is that file and by extention the InputStream is empty.
package com.test;
import org.springframework.extensions.webscripts.Cache;
import org.springframework.extensions.webscripts.DeclarativeWebScript;
import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptRequest;
import org.springframework.extensions.webscripts.servlet.FormData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.io.File;
import java.io.OutputStream;
import java.io.FileOutputStream;
public class UploadPdfWebScript extends DeclarativeWebScript {
private static Log logger = LogFactory.getLog(UploadPdfWebScript.class);
protected Map<String, Object> executeImpl(
WebScriptRequest req, Status status, Cache cache) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("fromJava", "HelloFromJava");
logger.debug("Your 'UploadPdf' Web Script was called!");
final FormData form = (FormData)req.parseContent();
InputStream file1 = null;
if(form == null || form.getFields() == null) {
return model;
}
for (FormData.FormField field : form.getFields())
{
if (field.getName().equals("pdf1"))
{
file1 = field.getInputStream();
}
}
String result = "this should be overwritten";
try{
result = processFile(file1);
} catch(Exception e) {
logger.error(e.getMessage());
}
if(result == null || result.equals("")) {
result = "No result";
}
model.put("newFile", result);
return model;
}
public String processFile(InputStream file) {
String ret = "{\”Result\": Success}”;
try {
byte[] buffer = new byte[file.available()];
file.read(buffer);
File targetFile = new File("targetFile.pdf");
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer2);
} catch (Exception e) {
ret = "{\”Result\": Failure}”;
logger.error(e.getMessage(), e);
}
return ret;
}
How can I get a pdf or other arbitrary file type from the InputStream? Again the InputStream that is returned from the form is empty whenever I try to upload a pdf and as a result so is the saved pdf.
Note: If I try to read the pdf from the local file system rather than sending it via a post request, this works fine. The pdf I'm uploading is definitely valid and not empty. I also know the webscript is being properly called as it is posting a log message, returning Success, and creating the targetFile.pdf which is empty.
Change this line:
outStream.write(buffer2);
To:
outStream.write(buffer);
Here's what shows up in the tomcat dir on my Docker container:
-rw-r----- 1 root root 117249 Aug 7 19:28 targetFile.pdf
Looks like it works!
I'm new to RESTful services and Jersey. I'm trying to create a ws that respond to POST call with enctype mutipart/form-data.
First of all I have my application Class
import com.ibm.sampleapp.rest.ConversationWS;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
#ApplicationPath("/api")
public class WinkApplication extends Application {
#Override
public Set<Class<?>> getClasses() {
enter code here
// Returns the list of classes which are to be added as REST endpoints
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MultiPartFeature.class);
classes.add(FormDataContentDisposition.class);
classes.add(RESTws.class);
return classes;
}
and then I have my rest service class
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.NumberFormat;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.OPTIONS;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
#Path("")
public class RESTws extends ResourceConfig {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_PLAIN)
public Response uploadFile(
#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileMetaData) throws Exception {
final ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(MultiPartFeature.class);
resourceConfig.register(FormDataContentDisposition.class);
String filename = fileMetaData.getFileName();
String uploadedFileLocation = "C:\\$User\\Doc\\" + filename;
try {
saveFile(uploadedInputStream, uploadedFileLocation);
}
catch(Exception e){
return Response.status(400).entity(e.getCause()).build();
}
String output = "File uploaded to: " + uploadedFileLocation;
System.out.println("File uploaded..");
return Response.status(200).entity(output).build();
}
// save uploaded file to a defined location on the server
private void saveFile(InputStream uploadedInputStream,
String serverLocation) {
try {
OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
int read = 0;
byte[] bytes = new byte[1024];
outpuStream = new FileOutputStream(new File(serverLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
outpuStream.write(bytes, 0, read);
}
outpuStream.flush();
outpuStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Finally i have the index.html in which i upload the file
<!DOCTYPE html>
<html>
<head>
<title>Java Web Starter Application</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>RESTful Web Service - File Upload Example</h1>
<form action="http://localhost:9080/java-sample-backend/api/upload" method="post" enctype="multipart/form-data">
<p>
Select a file to Upload to server: <input type="file" name="file" size="60" />
</p>
<input type="submit" value="Upload File" />
</form>
</body>
</html>
My dependencies are:
<!-- Jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-sse</artifactId>
<version>2.22.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.bundles</groupId>
<artifactId>jaxrs-ri</artifactId>
<version>2.21</version>
</dependency>
When I try to upload a file trough my html i get the following error:
[ERROR ] No message body reader has been found for class org.glassfish.jersey.media.multipart.FormDataContentDisposition, ContentType: multipart/form-data;boundary=---------------------------7e21f97403c2
Googling around the issue I understand that my problem is that I do not have my service registered, but I can not understand how I can achieve it.
Is there a way to do it programmatically and not via web.xml file?
-
Thank you very much for your help.
You need a class like MyRestApplication extends ResourceConfig that is annotated with #ApplicationPath("/PATH"). In the constructor of this class you call register( MultiPartFeature.class ); and register your service classes using registerClasses( MyService.class );.
The class MyService does not extend any other class but must be annotated by #Path("/SERVICEPATH"). This class then contains method uploadFile.
You don't need a web.xml.
I have written one jsp and corrosponding servelt in Intellij and running it in Tomcat local server from Intellij. Now without json file if I pass some normal text as output the servlet is working fine,but with json object its showing
java.lang.NoClassDefFoundError: org/json/simple/JSONObject
Servlet.UserInt.processRequest
---I have already imported json-simple -1,1.jar in external libraries so that its compiling but during servlet running it cant be loaded.
I also have created under web one folder named lib and have placed json and servet jar files there.
enter code here
UserInt.java---
public class UserInt extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
processRequest(request,response);
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
processRequest(request,response);
}
/* #Override
public String toString() {
return "UserInt{} " + super.toString();
}*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
response.setContentType("application/json");
try{
String query=request.getParameter("searchquery");
JSONObject json = new JSONObject();
json.put("query", query);
json.put("country", "India");
String output = json.toString();
PrintWriter writer = response.getWriter();
writer.write("output");
writer.flush();
writer.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
Index.jsp---
<form action="Servlet.UserInt" method="get" id="search-box">
<input type="text" class="search" name="searchquery" size="20" maxlength="120" placeholder="search...">
<input type="submit" class="button"value="Search">
<div class="set-parameter"><h3>User-Requirements</h3>
<i>Number of pages you want to see ?</i><input type="text" name="k" class="simple"/>
</div>
[enter image description here][1]
</form>
Can anyone please help me to solve this error? Thanks in advance!!
Check if correct org.json jar-file is imported.
I created simple project in IDEA with such dependencies in pom.xml:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven-eu.nuxeo.org</id>
<url>https://maven-eu.nuxeo.org/nexus/content/repositories/public-releases</url>
</repository>
</repositories>
Servlet:
package servlets;
import org.json.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
#WebServlet ("/myservlet.do")
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<body>");
out.println("<h1>Hello Servlet Get</h1>");
JSONObject json = new JSONObject();
json.put("query", "query");
json.put("country", "India");
String output = json.toString();
out.println(output);
out.println("</body>");
out.println("</html>");
}
}
Result:
Hello Servlet Get
{"country":"India","query":"query"}
I run it on WildFly JBoss 10.2.0.Final
First of all I was searching and trying many ways which are described on stackoverflow but it still doesn't work.
I can't upload any file via ajax and SpringMVC. Here is my code. What can be wrong?
Dynamic Web Module 2.5
Spring 4
tomcat 6
jsp code:
<input type="file" id="myName" name="myName" /><br>
<input type="button" value="Upload" onclick="uploadMeNow()"/>
dependencies connected to uploading:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
javascript:
function uploadMeNow() {
var file = new FormData($("#myName"));
$.ajax({
url : "/m61/uploadMe",
data : {file: file},
type : "POST",
processData: false,
contentType: false,
cache: false,
success : function(response) {
if (response.indexOf("saved") >= 0) {
alert('ok')
}
},
error : function (xhr, status, error) {
alert(xhr.responseText);
if (xhr.responseText.indexOf("failed") >= 0) {
alert('not ok')
}
}
});
}
xml:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="20971520" />
<property name="maxInMemorySize" value="1048576" />
</bean>
controller:
#RequestMapping(value = "/uploadMe", method = RequestMethod.POST)
#ResponseBody
public String uploadMe(#RequestParam("file") MultipartFile file) {
System.out.println("aaa");
return "saved";
}
A result: the current request is not a multipart request.
I was also trying by adding to ajax:
headers: {'Content-type':'multipart/form-data'},
result: the request was rejected because no multipart boundary was found
Please help me.
I`m going right on this tutorial https://spring.io/guides/gs/uploading-files/
and implemented a multipart file upload controller.
However, stuck on getting this error:
type Exception report
message Request processing failed; nested exception is java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
description The server encountered an internal error that prevented it from fulfilling this request.
Here is my code for controller, just right from official tutorial:
package com.springapp.mvc;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
#Controller
public class FileUploadController {
#RequestMapping(value="/api/items/upload_image", method=RequestMethod.POST)
public #ResponseBody String handleFileUpload(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file){
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(name)));
stream.write(bytes);
stream.close();
return "You successfully uploaded " + name + "!";
} catch (Exception e) {
return "You failed to upload " + name + " => " + e.getMessage();
}
} else {
return "You failed to upload " + name + " because the file was empty.";
}
}
}
And just for additional info, this is how i send request from front-end on angularjs. Request senging successfully:
Upload.upload({
url: '/api/items/upload_image',
file: $file,
name: $file.name,
progress: function(e){}
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
What i the problem can be?
All needed dependencies included.
This was a solution:
include this dependencies in pom.xml
<!-- Apache Commons FileUpload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<!-- Apache Commons IO -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Add this bean in configuration:
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="100000" />
</bean>