Multipart data sending got 408 Status - java

guys. Need help with sending POST request with multipart-data.
I have a method to create request on my client side. Here it is:
public void sendMultipart(String cmd , Employee emp) {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost uploadFile = new HttpPost(baseUrl + cmd);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody f = new FileBody(emp.getPhoto());
try {
StringBody s = new StringBody(emp.getLogin());
builder.addPart("name", s);
builder.addPart("file", f);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(RestTemplateRequester.class.getName()).log(Level.SEVERE, null, ex);
}
uploadFile.setHeader("Accept", "application/json");
uploadFile.setHeader("Content-type", "application/json");
uploadFile.setHeader("enctype","multipart/form-data");
uploadFile.setHeader("accept-charset","UTF-8");
//builder.addTextBody("field1", "yes", ContentType.TEXT_PLAIN);
//builder.addBinaryBody(emp.getLogin(), emp.getPhoto(), ContentType.MULTIPART_FORM_DATA, "file");
HttpEntity multipart = builder.build();
uploadFile.setEntity(multipart);
try {
HttpResponse httpResponse = httpClient.execute(uploadFile);
int status = httpResponse.getStatusLine().getStatusCode();
String str = httpResponse.getStatusLine().getReasonPhrase();
} catch (IOException ex) {
Logger.getLogger(RestTemplateRequester.class.getName()).log(Level.SEVERE, null, ex);
}
}
Also I have a method to handle request on my server side:
#RequestMapping(value = "photo", consumes = "multipart/form-data")
public #ResponseBody
void uploadFileHandler(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
// Create the file on server
File serverFile = new File(name);
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(serverFile));
stream.write(bytes);
stream.close();
} catch (Exception e) {
e.getMessage();
}
}
}
And in my context:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="100000" />
</bean>
The problem which I have now - is a 408 error "Request Time Out".
My common aim is - send JSON with file to server. I so green with web services in java, so i got some troubles.
Please, It will be great, if someone can give me a little advice. Thank you.

What you are trying to do is not an accepted way to upload file (Embedding file inside of JSON). And furthermore your Upload file handler is not suited to handle JSON instead in can handle only a multipart file and a name as parameter. Please look at my previous q/a on how to successfully upload a file using Spring MVC Multipart and RestTemplate.

Related

How to write java web services to upload image from android and use it in android

I see almost all webservice for android are written in PHP code. With Java I found an example of a rest service to upload image. I coded follow that code but when run test on my android device and Advanced RESTClient of chorme, I get error: HTTP Status 500 - Internal Server Error: Servlet.init () for servlet [Jersey REST Service] threw exception.. My URL: "http://srv.triaxvn.com:8080/logisticwsm/file/image-upload"
In android I use code:
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
File sourceFile = new File(filePath);
String fileName = sourceFile.getName();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(FILE_UPLOAD_URL);
MultipartEntity entity = new MultipartEntity();
// Extra parameters if you want to pass to server
entity.addPart("fileDescription", new StringBody(""));
entity.addPart("fileName", new StringBody(fileName != null ? fileName : sourceFile.getName()));
// Adding file data to http body
FileBody fileBody = new FileBody(sourceFile, "application/octect-stream") ;
entity.addPart("attachment", fileBody);
//totalSize = entity.getContentLength();
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
My Restful web service code:
#Path("/file")
public class UploadFile {
private final String UPLOADED_FILE_PATH = "c:\\uploaded";
#POST
#Path("/image-upload")
#Consumes("multipart/form-data")
public Response uploadFile(MultipartFormDataInput input) throws IOException
{
//Get API input data
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
//Get file name
String fileName = uploadForm.get("fileName").get(0).getBodyAsString();
//Get file data to save
List<InputPart> inputParts = uploadForm.get("attachment");
for (InputPart inputPart : inputParts)
{
try
{
//Use this header for extra processing if required
#SuppressWarnings("unused")
MultivaluedMap<String, String> header = inputPart.getHeaders();
// convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class, null);
byte[] bytes = IOUtils.toByteArray(inputStream);
// constructs upload file path
fileName = UPLOADED_FILE_PATH + fileName;
writeFile(bytes, fileName);
System.out.println("Success !!!!!");
}
catch (Exception e)
{
e.printStackTrace();
return Response.status(200).entity("Uploaded file name : "+e.getMessage()).build();
}
}
return Response.status(200)
.entity("Uploaded file name : "+ fileName).build();
}
//Utility method
private void writeFile(byte[] content, String filename) throws IOException
{
File file = new File(filename);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fop = new FileOutputStream(file);
fop.write(content);
fop.flush();
fop.close();
}
I do not know the error caused from by android code or Server Restful code and how to fix it

Android: Uploading video as a POST request to Java Backend?

I need to simply upload a video from my Android Device to my Java Backend and after reading through some StackOverflow threads, I learnt that I need to POST my video as a Multipart request to the Java Backend.
I managed to implement the following, which basically POSTs the video file as a Multipart POST request.
Android Client:
private void uploadVideo(String videoPath) throws ParseException, IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("MY_SERVER_URL");
FileBody filebodyVideo = new FileBody(new File(videoPath));
StringBody title = new StringBody("Filename: " + videoPath);
StringBody description = new StringBody("This is a description of the video");
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("video", filebodyVideo);
reqEntity.addPart("title", title);
reqEntity.addPart("description", description);
httppost.setEntity(reqEntity);
// DEBUG
HttpResponse response = httpclient.execute( httppost );
HttpEntity resEntity = response.getEntity( );
// DEBUG
System.out.println( response.getStatusLine( ) );
if (resEntity != null) {
System.out.println( EntityUtils.toString(resEntity) );
} // end if
if (resEntity != null) {
resEntity.consumeContent( );
} // end if
httpclient.getConnectionManager( ).shutdown();
}
My question is, how do I receive the file from the Java Backend? Here's the Backend method that I need to modify. Can someone point out how I can receive the video file from the backend?
What I have right now:
#Path("/user")
public class UserAPI {
#POST
//To receive the file, What do I add below instead of the lines I've commented.
//#Produces(MediaType.APPLICATION_JSON)
//#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Path("/postvideo")
public VideoResponse PostVideo(){
//My code
}
}
Here is how I did it (without error handling, validation and stuff).
#POST
#Path("/")
#Consumes("multipart/form-data")
public Response uploadFileMultipart(MultipartFormDataInput input) {
Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
List<InputPart> inputParts = uploadForm.get("video");
String videoFileName = "GENERATE_YOUR_FILENAME_HERE.mp4";
File file = new File(filename);
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fop = new FileOutputStream(file);
for (InputPart inputPart : inputParts) {
InputStream inputStream = inputPart.getBody(InputStream.class, null);
byte[] content = IOUtils.toByteArray(inputStream);
fop.write(content);
}
fop.flush();
fop.close();
return Response.status(HttpStatus.SC_OK).build();
}

"Decoding error, image format unsupported" in Microsoft Face API

I'm trying to use Microsoft Face API. For that I have the following code that was given by Microsoft as a sample (at the end of this page https://dev.projectoxford.ai/docs/services/563879b61984550e40cbbe8d/operations/563879b61984550f30395236):
HttpClient httpclient = HttpClients.createDefault();
try {
URIBuilder builder = new URIBuilder("https://api.projectoxford.ai/face/v1.0/detect");
builder.setParameter("returnFaceId", "false");
builder.setParameter("returnFaceLandmarks", "false");
builder.setParameter("returnFaceAttributes", "age,gender");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", "...");
String body = Base64.encodeBase64String(img);
StringEntity reqEntity = new StringEntity(body);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
return JsonParser.parse(EntityUtils.toString(entity));
}
} catch (URISyntaxException | IOException | ParseException e) {
System.out.println(e.getMessage());
}
return null;
but I get the following error:
{"error":{"code":"InvalidImage","message":"Decoding error, image format unsupported."}}
The image that I am using for tests is this one:
http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg
(found it on the internet in a quick search)
It respect all the requisits set by Microsoft, size and format... If I use it in the site it works https://www.projectoxford.ai/demo/face#detection
The String body from the convertion of my array of bytes to a string in base64 is also ok, I test it in this website: http://codebeautify.org/base64-to-image-converter
The error message it's quite simple, but I fail to see where I am worng. Anyone might know whats the problem?
UPDATE
The variable img:
img = Files.readAllBytes(Paths.get(imgPath));
I managed to discover the problem... Instead of:
String body = Base64.encodeBase64String(img);
StringEntity reqEntity = new StringEntity(body);
request.setEntity(reqEntity);
I needed to do:
ByteArrayEntity reqEntity = new ByteArrayEntity(img, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
I think that the Documentation is outdated...
I made the following change. Instead of sending an encoded image, I am sending the URL for the image.
request.setHeader("Content-Type", "application/json");
request.setHeader("Ocp-Apim-Subscription-Key", "{YOUR_FACES_API_KEY}");
StringEntity reqEntity = new StringEntity("{ \"url\":\"http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg\" }");
request.setEntity(reqEntity);
This gets the response:
[{"faceRectangle":{"top":878,"left":2718,"width":312,"height":312},"faceAttributes":{"gender":"male","age":28.5}},{"faceRectangle":{"top":593,"left":573,"width":310,"height":310},"faceAttributes":{"gender":"male","age":27.5}},{"faceRectangle":{"top":1122,"left":1014,"width":294,"height":294},"faceAttributes":{"gender":"female","age":27.7}},{"faceRectangle":{"top":915,"left":1773,"width":277,"height":277},"faceAttributes":{"gender":"female","age":36.7}},{"faceRectangle":{"top":566,"left":1276,"width":269,"height":269},"faceAttributes":{"gender":"male","age":40.7}},{"faceRectangle":{"top":677,"left":2134,"width":257,"height":257},"faceAttributes":{"gender":"female","age":35.2}}]
Will work on sending an encoded image soon. Will update this post accordingly.
EDIT:
Downloading image from URL
String base64Img = null;
byte[] bytes = null;
String imgBinaryString = null;
String base64ImgBinaryString = null;
try {
URL url = new URL("http://www.businessstudynotes.com/wp-content/uploads/2015/09/Role-of-Group.jpg");
//"http://www.huntresearchgroup.org.uk/images/group/group_photo_2010.jpg");
BufferedImage image = ImageIO.read(url);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
bytes = baos.toByteArray();
StringBuilder sb = new StringBuilder();
for (byte by: bytes)
sb.append(Integer.toBinaryString(by & 0xFF));
imgBinaryString = sb.toString();
base64Img = Base64.getEncoder().encodeToString(bytes);
byte[] base64Bytes = base64Img.getBytes("UTF-8");
sb = new StringBuilder();
for (byte by: base64Bytes) {
sb.append(Integer.toBinaryString(by & 0xFF));
}
base64ImgBinaryString = sb.toString();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
System.out.println("Download issue");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("ImageIO issue");
e.printStackTrace();
}
imgBinaryString contains a binary representation of the image; base64ImgBinaryString contains a binary representation of the Base 64 representation of the image.
To upload this image...
URI uri = builder.build(); // builder = new URIBuilder("https://api.projectoxford.ai/face/v1.0/detect");
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", "{YOUR_FACES_API_KEY");
StringEntity reqEntity = new StringEntity(base64ImgBinaryString);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
Setting the StringEntity to both imgBinaryString and base64ImgBinaryString results in the same response...
{"error":{"code":"InvalidImage","message":"Decoding error, image format unsupported."}}
Now, the good stuff. This works...
ByteArrayEntity reqEntity = new ByteArrayEntity(bytes, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
where bytes is the byte-array for the image; but a Base64 representation of this doesn't work. Someone really needs to update the documentation.
You could take a look at CognitiveJ, an open source library that will handle the communications & interactions with the MS faces API. If you don't want to use the library then you can have a look at the code to see what the REST API expects.
(disclosure - I'm the author of the library).
import okhttp3.*;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
doRequest();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void doRequest() throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("application/octet-stream"),
new File(".//src//main//java//Archivo_001.png"));
Request request = new Request.Builder()
.url("https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=false&returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,occlusion,accessories,blur,exposure,noise")
.post(body)
.addHeader("Ocp-Apim-Subscription-Key", "1d88f949af3443ea8cc16b7146bd7501")
.addHeader("Content-Type", "application/json")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
Hoping that this answer would be helpful to someone in the future, since I struggled with this quite a bit before finding this thread and realising the issue was on the documentation.
I managed to get the octet-stream type request working with HttpClient and RestTemplate.
HttpClient version:
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder(String.format("https://%s.api.cognitive.microsoft.com/face/v1.0/detect", region));
List<String> faceAttributes = Arrays.asList("age","gender","headPose","smile","facialHair","glasses","emotion","hair","makeup","occlusion","accessories","blur","exposure","noise");
String faceAttributesCommaSeparated = String.join(",", faceAttributes);
builder.setParameter("returnFaceId", "true");
builder.setParameter("returnFaceLandmarks", "false");
builder.setParameter("returnFaceAttributes", faceAttributesCommaSeparated);
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
ByteArrayEntity reqEntity = new ByteArrayEntity(fileContentBytes, ContentType.APPLICATION_OCTET_STREAM);
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = (HttpEntity) response.getEntity();
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
RestTemplate:
private RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.add("Ocp-Apim-Subscription-Key", subscriptionKey);
List<String> faceAttributes = Arrays.asList("age","gender","headPose","smile","facialHair","glasses","emotion","hair","makeup","occlusion","accessories","blur","exposure","noise");
String faceAttributesCommaSeparated = String.join(",", faceAttributes);
MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
paramsMap.add("returnFaceId", "true");
paramsMap.add("returnFaceLandmarks", "false");
paramsMap.add("returnFaceAttributes", faceAttributesCommaSeparated);
HttpEntity<byte[]> requestEntity = new HttpEntity<>(fileContentBytes, headers);
ResponseEntity<String> response = null;
try {
response = restTemplate.exchange(
String.format("%s/face/v1.0/detect", endpoint),
HttpMethod.POST,
requestEntity,
String.class,
paramsMap
);
} catch (HttpClientErrorException e) {
e.printStackTrace();
}
I left some specific values as variables but the gist of it should be clear. I will be using the restTemplate version in production code with a few minor changes.

How to use MultipartEntity in android http post

I have doubt for MultipartEntity.
First it is deprecated or not.
Second how to import MultipartEntity in my project.where to find jars.
I did add jars from Apache httpclient-4.4.1,httpcore-4.4.1,httpmime-4.4.1 into my project libs folder.
But i did not use multipartEntity any mistakes in my side please help me?
I want to upload image from android to spring controller.
Android code is:
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("userMO", jsonUserMo));
HttpPost post = new HttpPost(Constants.ROOTURL+"/media/uploadUserImage");
post.setHeader("Content-type", "multipart/form-data; boundary=***");
post.setEntity(new FileEntity(profileImage,"image/jpeg"));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = client.execute(post);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
contactLists.append(rd.readLine());
} catch (Exception e) {
e.printStackTrace();
}
My Spring Controller :
#RequestMapping(value = { "/uploadUserImage" }, method = RequestMethod.POST)
public #ResponseBody
String uploadUserImage(#RequestParam(value = "uploadImg") MultipartFile file, #RequestParam("userMO") String userBO, HttpSession session, HttpServletRequest httpServletRequest) {
log.info("hitting image");
UserBO userBo = gson.fromJson(userBO, UserBO.class);
// jboss file location to store images
String filePath = httpServletRequest.getSession().getServletContext().getRealPath("/") + "\\resources\\userImages\\" + userBo.getRingeeUserId() + ".png";
String fileName = file.getOriginalFilename();
try {
if (!file.isEmpty() && file.getBytes().length >= 5242880) {
log.info("file size is "+file.getBytes());
}
if (!file.isEmpty()) {
BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(file.getBytes()));
BufferedImage resizedImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
// resizedImage = originalImage.getSubimage(x1, y1, w, h);
File destination = new File(filePath);
// save cropped image
ImageIO.write(resizedImage, "jpeg", destination);
}
} catch (Exception Exp) {
log.info("Upload image failure");
}
return "";
}
I got error in android "http status 400-RequiredMultipartFile parameter 'uploadImg' is not present"
How to solve this?
try {
MultipartEntity entity = new MultipartEntity();
entity.addPart("type", new StringBody("uploadImg"));
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
}
You should add the addPart property with your multipart entity in order to get the additional parameter which your servlet is expecting on the server end. uploadImg in your case is the additional parameter expecting by the server in your request. Hope it will resolve your problem.

How to get multipartentity from httpservletrequest

I am trying to invoke a webservice from java spring controller. Below is the code
private void storeImages(MultipartHttpServletRequest multipartRequest) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(
"http://localhost:8080/dream/storeimages.htm");
MultipartFile multipartFile1 = multipartRequest.getFile("file1");
MultipartEntity multipartEntity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addPart("file1",
new ByteArrayBody(multipartFile1.getBytes(),
multipartFile1.getContentType(),
multipartFile1.getOriginalFilename()));
postRequest.setEntity(multipartEntity);
HttpResponse response = httpClient.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
}
Above is just partial code. I am trying to determine how to retrieve this on the server side. On the server side i have the following Spring controller code
#RequestMapping(value = "/storeimages.htm", method = RequestMethod.POST)
public ModelAndView postItem(HttpServletRequest request,
HttpServletResponse response) {
logger.info("Inside /secure/additem/postitem.htm");
try {
// How to get the MultipartEntity object here. More specifically i
// want to get back the Byte array from it
} catch (Exception ex) {
ex.printStackTrace();
}
return new ModelAndView("success");
}
I executed this code and my control is going to the server side. But i am stuck on how to get back the byte array from the multipartentity object.
Edited requirement:
Here is the requirement. User uploads the images from website (This is done and working) The control goes to the Spring controller after form submit (This is done and working) In Spring controller I am using Multipart to get the content of the form. (This is done and working) Now i want to call a webservices which will send the image byte array to image server.(This needs to be done) On the image server, i want to receive this webservice request get all the fields from HTTPServlerRequest, store the images and return(This needs to be done)
Finally resolved it. Here is what worked for me.
Client side
private void storeImages(HashMap<String, MultipartFile> imageList) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://localhost:8080/dream/storeimages.htm");
MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
Set set = imageList.entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
String fileName = (String)me.getKey();
MultipartFile multipartFile = (MultipartFile)me.getValue();
multipartEntity.addPart(fileName, new ByteArrayBody(multipartFile.getBytes(),
multipartFile.getContentType(), multipartFile.getOriginalFilename()));
}
postRequest.setEntity(multipartEntity);
HttpResponse response = httpClient.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
String output;
while ((output = br.readLine()) != null) {
logger.info("Webservices output - " + output);
}
httpClient.getConnectionManager().shutdown();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Server side
#RequestMapping(value = "/storeimages.htm", method = RequestMethod.POST)
public void storeimages(HttpServletRequest request, HttpServletResponse response)
{
logger.info("Inside /secure/additem/postitem.htm");
try
{
//List<Part> formData = new ArrayList(request.getParts());
//Part part = formData.get(0);
//Part part = request.getPart("file1");
//String parameterName = part.getName();
//logger.info("STORC IMAGES - " + parameterName);
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Set set = multipartRequest.getFileMap().entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
String fileName = (String)me.getKey();
MultipartFile multipartFile = (MultipartFile)me.getValue();
logger.info("Original fileName - " + multipartFile.getOriginalFilename());
logger.info("fileName - " + fileName);
writeToDisk(fileName, multipartFile);
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public void writeToDisk(String filename, MultipartFile multipartFile)
{
try
{
String fullFileName = Configuration.getProperty("ImageDirectory") + filename;
FileOutputStream fos = new FileOutputStream(fullFileName);
fos.write(multipartFile.getBytes());
fos.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
In my project, we used to use MultipartParser from com.oreilly.servlets to handle HttpServletRequests corresponding to multipart requests, as follows:
// Should be able to handle multipart requests upto 1GB size.
MultipartParser parser = new MultipartParser(aReq, 1024 * 1024 * 1024);
// If the content type is not multipart/form-data, this will be null.
if (parser != null) {
Part part;
while ((part = parser.readNextPart()) != null) {
if (part instanceof FilePart) {
// This is an attachment or an uploaded file.
}
else if (part instanceof ParamPart) {
// This is request parameter from the query string
}
}
}
Hope this helps.
Instead of doing all that by hand, you can use Springs Mutlipart support
The controller can work like this (This example use a command object to store additional user inputs -- (this is an example from an working project)).
#RequestMapping(method = RequestMethod.POST)
public ModelAndView create(#Valid final DocumentCreateCommand documentCreateCommand,
final BindingResult bindingResult) throws IOException {
if (bindingResult.hasErrors()) {
return new ModelAndView("documents/create", "documentCreateCommand", documentCreateCommand);
} else {
Document document = this.documentService.storeDocument(
documentCreateCommand.getContent().getBytes(),
StringUtils.getFilename(StringUtils.cleanPath(documentCreateCommand.getContent().getOriginalFilename())));
//org.springframework.util.StringUtils
return redirectToShow(document);
}
}
#ScriptAssert(script = "_this.content.size>0", lang = "javascript", message = "{validation.Document.message.notDefined}")
public class DocumentCreateCommand {
#NotNull private org.springframework.web.multipart.MultipartFile content;
Getter/Setter
}
To enable Spring Multipart support you need to configure some stuff:
web.xml (Add org.springframework.web.multipart.support.MultipartFilter after CharacterEncodingFilter and before HttpMethodFilter)
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<!-- uses the bean: filterMultipartResolver -->
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In your Spring Configuration for the CORE (not MVC Servlet) of your application add this
<!-- allows for integration of file upload functionality, used by an filter configured in the web.xml -->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="filterMultipartResolver" name="filterMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>
Then you also need the commons fileupload libary, because the Spring MultipartFile is just some kind of Addapter
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
For some more Details:
#See Spring Reference, Chapter 15.8 Spring's multipart (fileupload) support
to deal with spring files to the controller. you need to indicate, in your app-config.xml as follows:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
and treat code as follows
MultipartEntityBuilder paramsBuilder = MultipartEntityBuilder.create();
Charset chars = Charset.forName("UTF-8");
paramsBuilder.setCharset(chars);
if (null != obj.getFile()){
FileBody fb = new FileBody(obj.getFile());
paramsBuilder.addPart("file", fb);
}
and this for red multipart
private File getFile(MultipartFile file) {
try {
File fichero = new File(file.getOriginalFilename());
fichero.createNewFile();
FileOutputStream fos = new FileOutputStream(fichero);
fos.write(file.getBytes());
fos.close();
return fichero;
} catch (Exception e) {
return null;
}
}
I hope this helps.

Categories

Resources