I have little experience with configuring Spring and I'm having a hard time doing so. What I'm trying to do, is successfully map a url to a Controller using annotations. Furthermore, I'd like to have acces to the HttpRequest and optionally the HttpResponse. This is because I'd like to use Jackson to write and parse json directly to/from the bytestreams. Now I know Spring has JSON views using Jackson built in, but I'd like to get a decent foothold first as now I can't seem to get the mapping properly configured.
web.xml
<display-name>Kerris 2</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*-config.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
app-confix.xml
<context:annotation-config />
<context:component-scan base-package="servlet" />
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
DayController
package servlet;
#Controller
#RequestMapping("/days/*")
public class DayController {
private DayDAO dayDao;
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody void test(HttpResponse response){
System.out.println("Days GET");
}
#RequestMapping(method = RequestMethod.POST)
public #ResponseBody void test2(HttpRequest request, HttpResponse response){
System.out.println("Days POST");
}
public void setDaydao(DayDAO dayDao) {
this.dayDao = dayDao;
System.out.println("Days Dao assigned");
}
}
When I look at my server log I can see the following lines in there
INFO: Mapped URL path [/days/*] onto handler 'dayController'
INFO: Mapped URL path [/days/*.*] onto handler 'dayController'
INFO: Mapped URL path [/days/*/] onto handler 'dayController'
Also when I test the application at contextroot/ I see the standard Hello World! page. When I try contextroot/days/ I get a 404. When I try contextroot/days/test also 404. Could anybody point me at what I'm doing wrong?
Found out what I was doing wrong. As the n00b I am I didn't realize I have to specifically define a DispatcherServlet which hands the request over to the controller.
Web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/*-config.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>api</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
api-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="servlet" />
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
</beans>
When I try to call {contextroot}/api/days/ the request reaches the controller.
Related
I have tried to do simple file upload using JSF 2.1 and Primefaces 3.5.I can attach the file in UI.When I click submit button after attached the file it returns null pointer exception.
upload2.xhtml
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Journaldev Tutorial</title>
</h:head>
<h:body>
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{fileUploadManagedBean.file}" mode="simple"></p:fileUpload>
<p:separator/>
<h:commandButton value="Upload" ajax="false" action="#{fileUploadManagedBean.dummyAction}"></h:commandButton>
</h:form>
</h:body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>Testty3</display-name>
<welcome-file-list>
<welcome-file>faces/upload2.xhtml</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<multipart-config/>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.jsf</url-pattern>
<url-pattern>/icefaces/*</url-pattern>
</servlet-mapping>
<!-- <filter>
<filter-name>MyFacesExtensionsFilter</filter-name>
<filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFacesExtensionsFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping> -->
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!-- <context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param> -->
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value>
</context-param>
<!-- <listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener> -->
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<description>
This parameter tells MyFaces if javascript code should be allowed in
the rendered HTML output.
If javascript is allowed, command_link anchors will have javascript code
that submits the corresponding form.
If javascript is not allowed, the state saving info and nested parameters
will be added as url parameters.
Default is 'true'</description>
<param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<description>
If true, rendered HTML code will be formatted, so that it is 'human-readable'
i.e. additional line separators and whitespace will be written, that do not
influence the HTML code.
Default is 'true'</description>
<param-name>org.apache.myfaces.PRETTY_HTML</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<description>
If true, a javascript function will be rendered that is able to restore the
former vertical scroll on every request. Convenient feature if you have pages
with long lists and you do not want the browser page to always jump to the top
if you trigger a link or button action that stays on the same page.
Default is 'false'
</description>
<param-name>org.apache.myfaces.AUTO_SCROLL</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
</listener>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.icefaces.coalesceResources</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>org.icefaces.strictSessionTimeout</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.REFRESH_TRANSIENT_BUILD_ON_PSS_PRESERVE_STATE</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>false</param-value>
</context-param>
<mime-mapping>
<extension>png</extension>
<mime-type>image/png</mime-type>
</mime-mapping>
</web-app>
FileUploadManagedBean.java
package com.journaldev.prime.faces.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.RequestScoped;
import org.primefaces.model.UploadedFile;
#ManagedBean
#RequestScoped
public class FileUploadManagedBean {
UploadedFile file;
public UploadedFile getFile() {
System.out.println("getFile()");
return file;
}
public void setFile(UploadedFile file) {
System.out.println("setFile()");
this.file = file;
}
public String dummyAction(){
System.out.println("Uploaded File Name Is " + file.getFileName());
//System.out.println("Uploaded File Name Is :: "+file.getFileName()+" :: Uploaded File Size :: "+file.getSize());
return "";
}
}
javax.faces.FacesException: Error calling action method of component with id j_id_5:__9
at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:119)
at javax.faces.component.UICommand.broadcast(UICommand.java:120)
at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:1013)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:284)
at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1302)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:745)
at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:38)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: org.apache.myfaces.view.facelets.el.ContextAwareELException: javax.el.ELException: java.lang.NullPointerException
at org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:108)
at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:72)
... 29 more
Caused by: javax.el.ELException: java.lang.NullPointerException
at org.apache.el.parser.AstValue.invoke(AstValue.java:268)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
at org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:96)
... 30 more
Caused by: java.lang.NullPointerException
at com.journaldev.prime.faces.beans.FileUploadManagedBean.dummyAction(FileUploadManagedBean.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
In my browser it shows javax.el.ELException: java.lang.NullPointerException. Can some one Please help to figure out the error
I am trying to implement Spring security by using storage in a database and I have the following problem
SEVERE: Exception starting filter springSecurityFilterChain
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'springSecurityFilterChain' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1168)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:281)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:962)
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:324)
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235)
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4660)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5298)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/security-config.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/jpaContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>carPark</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/servlet-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>carPark</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
my security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true">
<intercept-url pattern="/**" access="ROLE_USER" />
</http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
</beans:beans>
servlet-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<!-- <mvc:annotation-driven /> -->
<context:component-scan base-package="com.fortech.controller" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
I mannaged to start the tomcat server if i comment out jpaContext.xml path but when i enter the user and the password it says that ROLE_ADMIN is unknown.
Notice that you are using two context parameters named contextConfigLocation.
My guess it that by default the one of them will override the second one.
You can define the two xmls in one context-pram block i.e.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/security-config.xml
classpath:jpaContext.xml
</param-value>
</context-param>
Make sure that the jpaContext.xml is located correctly on the root of the classpath (using classpath: in spring)
Notice that the DispatcherServlet creates ApplicationContext, which is a child of the root ApplicationContext. Beans in a child ApplicationContext can reference beans of its parent ApplicationContext however, the parent ApplicationContext cannot refer to beans of the child ApplicationContext.
Note that you did not define any access pattern for ROLE_ADMIN but you have one for ROLE_USER.
Make sure that user_roles mapping are correct.
I often get an exception EclipseLink-4021 "Unable to acquire a connection from driver [null], user [null] and URL [null]" when my application start.
This mean that Eclipselink doesn't find persistence.xml defined to connect to MySQL.
My persistence.xml is in folder /WEB-INF/classes, I think this is the standard place.
When I start tomcat again and again it finally work.
When anything run well, I get this log.
[EL Info]: 2016-07-01 11:22:55.268--ServerSession(975412652)--EclipseLink, version: Eclipse Persistence Services - 2.6.3.v20160428-59c81c5
[EL Info]: connection: 2016-07-01 11:22:56.794--ServerSession(975412652)--/file:/D:/Workspace_Eclipse/xxxWebapp/target/classes/_db1 login successful
I think this could come from my WebApp's architecture but I don't understand what is going wrong.
My WebApp is develop with Java 8, ZK 8, EclipseLink 2.6.3, MySQL 5.7.10
At the init a HttpServlet (GlobalEnvProperties.java) is called to prepare things like connections to other database and quartz scheduler.
web.xml complete content :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd"
version="2.4">
<description>app</description>
<display-name>Webapp</display-name>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zul</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>zkLoader</servlet-name>
<url-pattern>*.zhtml</url-pattern>
</servlet-mapping>
<servlet>
<description>The asynchronous update engine for ZK</description>
<servlet-name>auEngine</servlet-name>
<servlet-class>org.zkoss.zk.au.http.DHtmlUpdateServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
<listener>
<description>ZK listener for session cleanup</description>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<session-config>
<session-timeout>14400</session-timeout>
</session-config>
<servlet>
<description>Gestion des environnements</description>
<servlet-name>GlobalEnvProperties</servlet-name>
<servlet-class>com.company.app.webapp.common.GlobalEnvProperties</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<mime-mapping>
<extension>doc</extension>
<mime-type>application/vnd.ms-word</mime-type>
</mime-mapping>
<mime-mapping>
<extension>gif</extension>
<mime-type>image/gif</mime-type>
</mime-mapping>
<mime-mapping>
<extension>htm</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpeg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>js</extension>
<mime-type>text/javascript</mime-type>
</mime-mapping>
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
<mime-mapping>
<extension>png</extension>
<mime-type>image/png</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/vnd.ms-excel</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xml</extension>
<mime-type>text/xml</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zhtml</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>zul</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>auth.zul</welcome-file>
</welcome-file-list>
</web-app>
In the init void of the servlet GlobalEnvProperties, I get EntityManager with Persistence.createEntityManagerFactory("db1")
public void init() throws ServletException {
bddFactories = new HashMap<String, EntityManagerFactory>();
entityManagers = new HashMap<String, EntityManager>();
//global properties
configProp = new Properties();
InputStream ficProperties = Thread.currentThread().getContextClassLoader().getResourceAsStream("META-INF/app.properties");
try {
configProp.load(new InputStreamReader(ficProperties, "UTF-8"));
} catch (IOException e) {
CustomLogger.info("Unable to open properties file");
CustomLogger.tracerErreurFatale(e);
}
/*
* BDD connection
*/
// Base db1
try {
final int sleepChargementPersitence = 10000;
Thread.sleep(sleepChargementPersitence);
bddFactories.put("db1", Persistence.createEntityManagerFactory("db1"));
} catch (javax.persistence.PersistenceException | DatabaseException e) {
CustomLogger.info("Unable to connect db1");
CustomLogger.tracerErreurFatale(e);
} catch (InterruptedException e) {
CustomLogger.info("Sleep failed");
}
OtherConnectionsLoad();
//scheduler
try {
CustomLogger.debug("Scheduler start");
DailyTreatmentScheduler.main(null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
My persistence.xml content :
?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="db1">
<class>com.company.app.model.Action</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="*******" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://server:3306/db1?useSSL=false" />
<property name="eclipselink.deploy-on-startup" value="true" />
<property name="javax.persistence.jdbc.initialSize" value="2" />
<property name="javax.persistence.jdbc.maxActive" value="10" />
<property name="javax.persistence.logging.level" value="INFO" />
<property name="eclipselink.query-results-cache" value="false" />
<property name="javax.persistence.refresh" value="true" />
</properties>
</persistence-unit>
</persistence>
I hope someone could explain where I'm wrong.
Thanks for those who will try to understand my problem.
I have configured below c3p0 settings in my project. But while executing the jar file, I have found "no writeable property". Kindly advise me how to solve this.
Configuration:-
dataSource.setClassName("com.mchange.v2.c3p0.ComboPooledDataSource");
dataSource.getDriverProperties().setProperty("driverClass", properties.getProperty("jdbc.driver"));
dataSource.setUniqueName(properties.getProperty("jbpm.uniquename"));
dataSource.setMaxPoolSize(Integer.parseInt(properties.getProperty("jbpm.max")));
dataSource.setAllowLocalTransactions(true);
dataSource.getDriverProperties().setProperty("URL", properties.getProperty("jbpm.url"));
dataSource.getDriverProperties().setProperty("user", properties.getProperty("jbpm.username"));
dataSource.getDriverProperties().setProperty("password", properties.getProperty("jbpm.password"));
dataSource.getDriverProperties().setProperty("acquireIncrement", properties.getProperty("jdbc.acquireincrement"));
dataSource.getDriverProperties().setProperty("preferredTestQuery", properties.getProperty("jdbc.preferredtestquery"));
dataSource.getDriverProperties().setProperty("breakAfterAcquireFailure", properties.getProperty("jdbc.breakafteracquirefailure"));
dataSource.getDriverProperties().setProperty("acquireRetryAttempts", properties.getProperty("jdbc.acquireretryattempts"));
dataSource.getDriverProperties().setProperty("acquireRetryDelay", properties.getProperty("jdbc.acquireretrydelay"));
dataSource.getDriverProperties().setProperty("loginTimeout", properties.getProperty("jdbc.logintimeout"));
dataSource.getDriverProperties().setProperty("idleConnectionTestPeriod", properties.getProperty("jdbc.dleconnectiontestperiod"));
dataSource.getDriverProperties().setProperty("maxPoolSize", properties.getProperty("jdbc.maxpoolsize"));
dataSource.getDriverProperties().setProperty("minPoolSize", properties.getProperty("jdbc.minpoolsize"));
Error log:-
bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named java:jboss/datasources/DS
at bitronix.tm.resource.jdbc.PoolingDataSource.init(PoolingDataSource.java:80)
at com.tnq.messageq.DataSource.init(DataSource.java:60)
at com.tnq.messageq.IntegrationConsumer.main(IntegrationConsumer.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.simontuffs.onejar.Boot.run(Boot.java:340)
at com.simontuffs.onejar.Boot.main(Boot.java:166)
Caused by: bitronix.tm.utils.PropertyException: no writeable property 'URL' in class 'com.mchange.v2.c3p0.ComboPooledDataSource'
at bitronix.tm.utils.PropertyUtils.getSetter(PropertyUtils.java:318)
at bitronix.tm.utils.PropertyUtils.setDirectProperty(PropertyUtils.java:217)
at bitronix.tm.utils.PropertyUtils.setProperty(PropertyUtils.java:83)
at bitronix.tm.resource.common.XAPool.createXAFactory(XAPool.java:314)
at bitronix.tm.resource.common.XAPool.<init>(XAPool.java:63)
at bitronix.tm.resource.jdbc.PoolingDataSource.buildXAPool(PoolingDataSource.java:89)
at bitronix.tm.resource.jdbc.PoolingDataSource.init(PoolingDataSource.java:76)
Thanks for looking into this..
ComboPooledDataSource has a property named JdbcUrl.Hence you can try using it instead of url.
dataSource.getDriverProperties().setProperty("jdbcUrl, properties.getProperty("jbpm.url"));
Hope this helps.
URL issue has been resolved. But after that I have found 'unable to find a bound object at name'. Please check and advise me.
For c3p0 migration, I have changed 'PoolingDataSource' to 'ComboPooledDataSource', after that I have configured the below setting in the init method.
Code:-
public static void init() throws Exception {
setPropertyMap();
properties = new Properties();
FileInputStream fileInput = new FileInputStream(new File("/home/data/settings."+map.get(System.getenv("spring_profiles_active"))+".properties"));
properties.load(fileInput);
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mchange.v2.c3p0.ComboPooledDataSource");
dataSource.setJdbcUrl(properties.getProperty("jbpm.url"));
dataSource.setUser(properties.getProperty("jbpm.username"));
dataSource.setPassword(properties.getProperty("jbpm.password"));
dataSource.setAcquireIncrement(Integer.parseInt(properties.getProperty("jdbc.acquireincrement")));
dataSource.setAcquireRetryDelay(Integer.parseInt(properties.getProperty("jdbc.acquireretrydelay")));
dataSource.setIdleConnectionTestPeriod(Integer.parseInt(properties.getProperty("jdbc.dleconnectiontestperiod")));
dataSource.setMaxPoolSize(Integer.parseInt(properties.getProperty("jdbc.maxpoolsize")));
dataSource.setMinPoolSize(Integer.parseInt(properties.getProperty("jdbc.minpoolsize")));
}
Error Log:-
Caused by: org.hibernate.HibernateException: Could not find datasource
at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:79)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143)
at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:51)
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:90)
at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2863)
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2859)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1870)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:906)
... 68 more
Caused by: javax.naming.NameNotFoundException: unable to find a bound object at name 'java:jboss/datasources/DS'
at bitronix.tm.jndi.BitronixContext.lookup(BitronixContext.java:83)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
... 75 more
JarClassLoader: Warning: com/mchange/Debug.class in lib/c3p0-0.9.5.1.jar is
persistence.xml:-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence version="1.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="org.jbpm.persistence.jpa.testcon">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/DS</jta-data-source>
<mapping-file>META-INF/JBPMorm.xml</mapping-file>
<class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
<class>org.drools.persistence.info.SessionInfo</class>
<class>org.drools.persistence.info.WorkItemInfo</class>
<class>org.jbpm.process.audit.ProcessInstanceLog</class>
<properties>
<property name="hibernate.max_fetch_depth" value="3"/>
<!--<property name="hibernate.hbm2ddl.auto" value="validate" />-->
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.BTMTransactionManagerLookup" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
</persistence>
web.xml:-
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Origin, X-Requested-With, Content-Type</param-value>
</init-param>
<init-param>
<param-name>cors.allowGenericHttpRequests</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Date</param-value>
</init-param>
</filter>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>com.test.hibernate.HibernateFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- To be used only when we need to deploy multiple wars in one container -->
<env-entry>
<env-entry-name>spring.profiles.active</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>testuat</env-entry-value>
</env-entry>
</web-app>
Main program calls init method.
public static void main(String[] argv) {
try {
DataSource.init();
applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext.xml");
..........
}
catch (Exception e) {
e.printStackTrace();
log.error(e.getStackTrace());
}
}
Thanks for looking into this..
I'm trying to call a method in Spring (3.2.0) via AJAX using the following jQuery 1.6.
function updateRoleEnabled(id)
{
$.ajax({
datatype:"json",
type: "PUT",
url: "/wagafashion/ajax/UpdateUserRole.htm",
data: "id="+id+"&t="+new Date().getTime(),
success: function(response)
{
},
error: function(e)
{
alert('Error: ' + e);
}
});
}
It attempts to invoke the following method in Spring.
#RequestMapping(value=("ajax/UpdateUserRole"), method=RequestMethod.PUT)
public #ResponseBody void updateUserRole(#RequestParam(value=("id")) String id)
{
System.out.println("id = "+id);
}
FireFox responds with the following error.
HTTP Status 405 - Request method 'GET' not supported
type Status report
message Request method 'GET' not supported
description The specified HTTP method is not allowed for the requested
resource (Request method 'GET' not supported).
Apache Tomcat/6.0.26
It works with the GET and POST methods and JSON (with Jackson-2.1.1) also works fine in other parts of the application.
If you need to see the dispatcher-servlet.xml file, the full contents is as follows.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="controller" />
<context:component-scan base-package="validatorbeans" />
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" >
<mvc:message-converters register-defaults="false">
<bean id="jacksonMessageConverter" p:supportedMediaTypes="application/json" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="false" />
<property name="ignoreAcceptHeader" value="false" />
<property name="mediaTypes" >
<value>
atom=application/atom+xml
html=text/html
json=application/json
*=*/*
</value>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">
fileUploadingFailure
</prop>
</props>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
How to make HTTP methods other than GET and POST work in Spring 3.2?
EDIT:
Based on the comment below, the following is my entire web.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>NoCacheFilter</filter-name>
<filter-class>filter.NoCacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>/admin_side/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>FileUploadFilter</filter-name>
<filter-class>com.ckfinder.connector.FileUploadFilter</filter-class>
<init-param>
<param-name>sessionCookieName</param-name>
<param-value>JSESSIONID</param-value>
</init-param>
<init-param>
<param-name>sessionParameterName</param-name>
<param-value>jsessionid</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FileUploadFilter</filter-name>
<url-pattern>
/ckfinder/core/connector/java/connector.java
</url-pattern>
</filter-mapping>
<filter>
<filter-name>multipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>multipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>openSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>openSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<description>ServletContextListener</description>
<listener-class>listener.UnregisterDatabaseDrivers</listener-class>
</listener>
<servlet>
<servlet-name>ConnectorServlet</servlet-name>
<servlet-class>com.ckfinder.connector.ConnectorServlet</servlet-class>
<init-param>
<param-name>XMLConfig</param-name>
<param-value>/WEB-INF/config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ConnectorServlet</servlet-name>
<url-pattern>
/ckfinder/core/connector/java/connector.java
</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
<error-page>
<description>Missing login</description>
<error-code>401</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Forbidden directory listing</description>
<error-code>403</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Missing page</description>
<error-code>404</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Uncaught exception</description>
<error-code>500</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<error-page>
<description>Unsupported servlet method</description>
<error-code>503</error-code>
<location>/WEB-INF/jsp/admin_side/ErrorPage.jsp</location>
</error-page>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
Unless one is using only path parameters, processing a regular HTTP PUT needs some more work.
Since Spring 3.1, HttpPutFormContentFilter can be used to make #RequestParam work for application/x-www-form-urlencoded data:
Filter that makes form encoded data available through the ServletRequest.getParameter*() family of methods during HTTP PUT requests.
The Servlet spec requires form data to be available for HTTP POST but not for HTTP PUT requests. This filter intercepts HTTP PUT requests where content type is 'application/x-www-form-urlencoded', reads form encoded content from the body of the request, and wraps the ServletRequest in order to make the form data available as request parameters just like it is for HTTP POST requests.
However: this filter consumes the request's input stream, making it unavailable for converters such as FormHttpMessageConverter, like used for #RequestBody MultiValueMap<String, String> or HttpEntity<MultiValueMap<String, String>>. As a result, once you have configured the above filter in your application, you will get "IOException: stream closed" when invoking methods that use other converters that also expect raw application/x-www-form-urlencoded PUT data.
Alternatively one can do everything manually, using #RequestBody or HttpEntity<?>:
#RequestMapping(value="ajax/UpdateUserRole", method=RequestMethod.PUT,
produces = MediaType.TEXT_PLAIN_VALUE)
public #ResponseBody String updateUserRole(
#RequestBody final MultiValueMap<String, String> data,
final HttpServletResponse response) {
Map<String, String> params = data.toSingleValueMap();
String id = params.get("id");
String a = params.get("a");
String b = params.get("b");
if(id == null || a == null || b == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return null;
}
return "id = " + id;
}
See also an example using WebDataBinder, or use:
public ResponseEntity<String> updateUserRole(
final HttpEntity<MultiValueMap<String, String>> entity) {
Map<String, String> params = entity.getBody().toSingleValueMap();
String id = params.get("id");
...
Note that for testing, using MockMvc's mockMvc.perform(put(url).param(name, value)) would actually also work with the code form the question, even though it would fail in a servlet container. But MockMvc is not running in such servlet container, hence is fooling you a bit.
MockMvc's .param(name, value) also works nicely with HttpPutFormContentFilter. But when using MockMvc to test #RequestBody or HttpEntity<?>, one also needs to create any application/x-www-form-urlencoded PUT content manually. Like:
mockMvc.perform(put(url).content("id=" + URLEncoder.encode(id, "UTF-8")
+ "&a=" + URLEncoder.encode(a, "UTF-8") + "&b=" + ...)
To be able to simply use .param(name, value), just like for GET and POST, one could define:
public static RequestPostProcessor convertParameters() {
return new RequestPostProcessor() {
#Override
public MockHttpServletRequest postProcessRequest(
final MockHttpServletRequest request) {
if ("PUT".equalsIgnoreCase(request.getMethod()) {
Map<String, String[]> params = request.getParameterMap();
if (params != null) {
StringBuilder content = new StringBuilder();
for (Entry<String, String[]> es : params.entrySet()) {
for (String value : es.getValue()) {
try {
content.append(URLEncoder.encode(es.getKey(), "UTF-8"))
.append("=")
.append(URLEncoder.encode(value, "UTF-8"))
.append("&");
}
catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("UTF-8 not supported");
}
}
}
request.setParameters(new HashMap<String, String[]>());
request.setContent(content.toString().getBytes());
request.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
}
}
return request;
}
};
}
...and then use .with(convertParameters()) next to .param(name, value):
mockMvc.perform(put(url)
.with(convertParameters())
.param("id", id).param("a", a).param("b", b) ...)
Given all the above, simply using HttpPutFormContentFilter for application/x-www-form-urlencoded data really makes life easier.
When the browser is not sending application/x-www-form-urlencoded data, but things such as JSON, then trying to map to MultiValueMap will yield 415 Unsupported Media Type. Instead, use something like #RequestBody MyDTO data or HttpEntity<MyDTO> entity as explained in Parsing JSON in Spring MVC using Jackson JSON.