404 when uploading files to Spring J2EE - java

My current code:
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST, headers = "Accept=*")
public void uploadFile(#RequestParam(value = "file") MultipartFile multipartFile,
Model model, HttpServletRequest request, HttpServletResponse response) {
String fileName = multipartFile.getOriginalFilename();
System.out.println(fileName);
}
Problem is that when I require the file to be there (not having "required=false" after value="file") Then it can't find the suitable path for my request (404).
I have checked in browsers that there are a file sent to the server, with the name="file":(copy paste from chrome browser follows)
------WebKitFormBoundaryS7qP6QevHhFOyAZN
Content-Disposition: form-data; name="file"; filename="testfile"
Content-Type: application/octet-stream
------WebKitFormBoundaryS7qP6QevHhFOyAZN--
I really could use a hint here, can anyone help me?
Thanks in advance

Were missing the following in mappings:
servlet context.xml:
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
root-context.xml:
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--25 mb max-->
<property name="maxUploadSize" value="26214400"/>
</bean>
and last In pom.xml (because i run maven project, else you need the jars)
<!-- Fileupload dependencies -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version> <!-- makesure correct version here -->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>

Related

406 Not acceptable error when returning JSON in Spring MVC

I am working on application which will just used as a restful services and the response has to be returned as JSON.y p
I am on Spring MVC and following this article to achieve the same
https://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/
I have added Jackson jar in my POM, enabled response body and mvc-annotation-driven annotation.
But still on firing the url i get 406 Not acceptable error.
I have tried firing with a rest client and adding request headers for Content-Type and Accept with "application/json".
Below is my POM with the dependencies part
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.10</version>
</dependency>
My spring config file
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.sap.cf.casestudy.controller" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
My controller code
import java.util.ArrayList;
import java.util.List;
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.ResponseBody;
import com.sap.cf.casestudy.domain.Employee;
#Controller
#RequestMapping("/employee")
public class EmployeeController {
#RequestMapping(method = RequestMethod.GET ,headers="Accept=application/json")
public #ResponseBody Employee getEmployee() {
List<Employee> empList = getEmployeeData();
return empList.get(0);
//return "employeelist";
}
private List<Employee> getEmployeeData(){
List<Employee> employeeList = new ArrayList<Employee>();
Employee emp1 = new Employee();
emp1.setFirstName("Saurav");
emp1.setLastName("Sarkar");
employeeList.add(emp1);
Employee emp2 = new Employee();
emp2.setFirstName("John");
emp2.setLastName("Doe");
employeeList.add(emp1);
return employeeList;
}
}
In addition i have a POJO of employee class with firstname and lastname as private methods and setter/getter as public methods.
Best Regards,
Saurav
Spring 4.3.10: I used the below settings to resolve the issue.
Step 1: Add the below dependencies
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.7</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
Step 2: Add the below in your MVC DispatcherServlet context configuration:
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"/>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false"/>
<property name="favorParameter" value="true"/>
<property name="ignoreAcceptHeader" value="false" />
</bean>
Since spring 3.2, as per the default configuration favorPathExtension is set as true, because of this if the request uri have any proper extensions like .htm spring will give priority for the extension. In step 2 I had added the contentNegotiationManager bean to override this.
I could resolve the problem with my above code itself.
Problem was the jackson mapper jar was not present in the classpath.
So it was not working.
In Eclipse For Maven projects you have to force update such that the jar can come in the classpath.
Ideally there should been an error from the spring framework about the class not being loaded. The error itself was misleading.
Best Regards,
Saurav
My simple setting. hope this helps a little bit
pom.xml
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.3</version>
</dependency>
servlet-context.xml
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<context:component-scan base-package="com.urong.sample" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven>
<mvc:message-converters>
<beans:bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<beans:property name="supportedMediaTypes">
<beans:list>
<beans:value>text/html;charset=UTF-8</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving
up static resources in the ${webappRoot}/resources directory -->
<mvc:resources location="/resources/" mapping="/resources/**" />
<mvc:default-servlet-handler />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources
in the /WEB-INF/views directory -->
<!-- Your Resolves -->
Controller
#RequestMapping(value = "/call", method = RequestMethod.POST)
public #ResponseBody String callTest(#RequestBody CompanyLocation location) {
// use location. this sample object
return "your return String";
}
client(my javascript)
function callTest() {
var companyIdx = $('#companyIdx').val();
var locationIdx = $('#locationIdx').val();
var data = {
idx : locationIdx,
postCode : $('#postCode').val(),
address : $('#address').val(),
detailAddress : $('#detailAddress').val(),
tel : $('#tel').val(),
fax : $('#fax').val(),
email : $('#email').val(),
language : $("#language").val(),
latitude : $('#latitude').val(),
longtitude : $('#longtitude').val()
};
data = JSON.stringify(data);
$.ajax({
url : "/sample/call,
type : 'POST',
data : data,
contentType : 'application/json',
success : function(response) {
// use response.
},
error : function(request, status, error) {
},
complete : function(data) {
}
});
}

Required MultipartFile parameter 'file' is not present error when trying upload a file

I don't know how to solve the problem. Googled it for hours without success:
simple example:
my form in jsp
<form method="post" action="/asd" enctype="multipart/form-data">
<input type="file" class="file" name="file"/>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="submit" value="Upload">
</form>
my Controller's method
#RequestMapping(value = "/asd", method = RequestMethod.POST)
public String handleFileUpload(
#RequestParam("file") MultipartFile file){
System.out.print(file);
return "string";
}
My context xml file
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- max upload size in bytes -->
<property name="maxUploadSize" value="20971520" /> <!-- 20MB -->
<!-- max size of file in memory (in bytes) -->
<property name="maxInMemorySize" value="1048576" /> <!-- 1MB -->
</bean>
I have in my pom.xml
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version> <!-- makesure correct version here -->
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
I even added allowCasualMultipartParsing="true" to every context.xml of my server as below:
<Context reloadable="true" allowCasualMultipartParsing="true">
but the error still occurs and I don't know what I am doing wrong:
HTTP Status 400 – Bad Request
Type Status Report
Message Required MultipartFile parameter 'file' is not present
Description The server cannot or will not process the request due to
something that is perceived to be a client error (e.g., malformed
request syntax, invalid request message framing, or deceptive request
routing).
Apache Tomcat/8.5.12
Try this,
Add bellow filters in your web.xml file
Web.xml
<!-- Support for File Upload And Download -->
<filter>
<display-name>springMultipartFilter</display-name>
<filter-name>springMultipartFilter</filter-name>
<filter- class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>springMultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
And also in your context file use filterMultipartResolver instead of multipartResolver because of Spring Security dependency as bellow
<!-- Support For File Upload And Download -->
<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000" />
</bean>
And yes Cheerssssssss!!!!!!!!

Spring SaajSoapMessageFactory - Exception in saving multipart

I am creating an application to upload a file from browser. The web service client was build using the spring SaajSoapMessageFactory. Using websphere.
pom.xml
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.3.16</version>
<scope>provided</scope>
</dependency>
dispatcher-servlet.xml
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="messageFactory">
<bean class="com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl" />
</property>
</bean>
The spring web service throws the following exception during the file upload.
Exception created : [org.springframework.ws.soap.saaj.SaajSoapMessageException: Could not write message to OutputStream: Error during saving a multipart message; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Error during saving a multipart message
at org.springframework.ws.soap.saaj.SaajSoapMessage.writeTo(SaajSoapMessage.java:251)
at org.springframework.ws.transport.AbstractWebServiceConnection.send(AbstractWebServiceConnection.java:45)

Error 406 in Spring MVC - migration from Spring 3.0.5 to Spring 4.2.4

I am in the process of migrating a web-app from Spring 3.0.5 to 4.2.4. After many hurdles (apparently the process is not really documented well...), I've hit the dreaded 406 error. It seems there are many questions all around, but none of the answers are working (even the questionable ones).
This is the controller code with the function:
#Controller
public class TestController {
#RequestMapping(value = "/echo", method = RequestMethod.GET, headers = "Accept=*/*")
#ResponseBody
public String echoReply(HttpServletRequest request) throws Exception {
return "echo";
}
#RequestMapping(value = "/test", method = RequestMethod.GET, headers = "Accept=*/*")
#ResponseBody
public boolean testFunc(HttpServletRequest request) throws Exception {
...
return ...;
}
The first function returns echo as expected, but the test function returns error 406 - Could not find acceptable representation. The exact message is:
The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request
"accept" headers
Both are relevant to AJAX calls and to direct access via URL.
Any ideas what to look for and why it happens that way?
Edit: perhaps this is some issue in controller class annotations (something missing that should be in Spring 4.2)?
app-context.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd" default-lazy-init="true">
<context:annotation-config />
<aop:aspectj-autoproxy />
<tx:annotation-driven/>
<mvc:annotation-driven/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="..." />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
// bunch of component-scans and some more beans
</beans>
pom.xml:
(relevant dependencies for Jackson)
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1-1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.7.1</version>
</dependency>
The official Spring MVC documentation lists the following data types as valid return types for controller methods:
ModelAndView
Model
Map
View
String
void
HttpEntity
HttpHeaders
Callable
DeferredResult
ListenableFuture
ResponseBodyEmitter
SseEmitter
StreamingResponseBody
For a controller method annotated with #ResponseBody the return type is written to the response body. This process is carried out using an HttpMessageConverter appropriate for the Accepts request header.
Since your testFunc method has a return type of boolean, Spring MVC will attempt to write the returned value using an HttpMessageConverter. This means, the Accepts header must specify a value that will result in a valid representation of a boolean value. Therefore, the representation can only be schemaless, such as JSON. Any other representation will lead to the described error.
Therefore, if your Accepts header is set to text/html or application/xml, boolean will fail to get written to the response body. If however you set the header to application/json, your boolean value will get written correctly.
If you want to support HTML and XML as well, you will have to wrap the boolean in an object such as a Map or a custom object.
Try to update app-context.xml with
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>

Spring REST MultipartFile file is always null

I'm trying to set up a simple upload with html and Spring 3.0.6 using REST services. I've followed the tutorial online but the MultipartFile parameter is always null. Here's the config and code:
application-context.xml:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="2000000"/>
</bean>
pom.xml:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
html:
<html>
<head>
<title>Upload a file please</title>
</head>
<body>
<h1>Please upload a file</h1>
<form method="post" action="/site/restServices/artworkUpload/" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
</body>
</html>
REST Controller:
#POST
#Path("/artworkUpload")
public String uploadFile(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
try {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
} else {
return "redirect:uploadFailure";
}
}
catch (Exception ex)
{
}
return null;
}
I copied the example from Spring's tutorial but no matter what I change, the file parameter is always null. "name" will have the value in the text box but file will be null.
I have also tried using Jersey and I receive the InputStream for the file but the FormDataContentDisposition is null so I can't determine the file type.
This is running on Jetty as well.
What am I missing?
As I remember I solved same issue by putting additional libs to my build path:
commons-fileupload-1.2.2.jar
commons-io-2.1.jar
I hope this will help you.
Edit.
Ok. At last I had time for this issue. First of all, why do you use standart java features for building rest service (annotations #POST, #Path)? Because with Spring it is better to use spring MVC futures for REST. There is a lot of information about this in internet. Here is special part in reference documentation. Also here is good article on IBM site. Also very good description on how to build REST controller with Spring MVC is in Spring in Action (last 3-d edition).
Here how I have implemented simple file uploading functionality:
Rest controller:
#Controller
#RequestMapping("/rest/files")
public class FilesController {
...
#RequestMapping(value="/rest/files", method=RequestMethod.POST)
public String uploadFile(#RequestParam("name") String name,
#RequestParam("file") MultipartFile file) {
try {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
} else {
return "redirect:uploadFailure";
}
}
catch (Exception ex)
{
}
return "/testFileDownload";
}
}
html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test file upload</title>
</head>
<body>
<h1>Please upload a file</h1>
<form method="post" action="rest/files" enctype="multipart/form-data">
<input type="text" name="name" /> <input type="file" name="file" /> <input
type="submit" />
</form>
</body>
</html>
View resolver configuration in dispatcher-servlet.xml:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="file" value="multipart/form-data"/>
<entry key="html" value="text/html"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
I hope I'm not wasted my time and this is still necessary for you. )
EDIT 2
Here is very good tutorial where described how to build RESTful web service with Spring 3.1.
It helped me to connect this library:
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
All libs:
<dependencies>
<!-- Spring 3 MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.1.2.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>
See http://viralpatel.net/blogs/spring-mvc-multiple-file-upload-example/

Categories

Resources