Spring Web Flow Request Mapping not working - spring

I am trying to test Spring Web Flow and cannot access the flow basing on the mapping I'm using. I'm sure I must be missing something simple, but here is my setup...
web.xml:
<servlet>
<servlet-name>accommodations</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>accommodations</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/datasource-config.xml
/WEB-INF/security-config.xml
/WEB-INF/webflow-config.xml
/WEB-INF/aop-config.xml
</param-value>
</context-param>
webflow configuration:
<flow:flow-registry id="flowRegistry" base-path="/WEB-INF/flows/" >
<flow:flow-location-pattern value="**/*-flow.xml"/>
</flow:flow-registry>
<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
</bean>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
</beans>
The flow xml defination is locations in "WEB-INF/flows/accommodations/accommodations-flow.xml",
so my understand is that /accommodations should map to the flow.
When I point the browser to /accommodations I receive a 404.
What mistake am I making..?

Related

Spring Web Flow 2.5.1.RELEASE with JSF2.2 flow not executed

I am struggling with this issue for 5 days now and I don't see where to look for a solution.
I upgraded a JSF application from 2.1 to 2.2 with Mojara 2.1.17 to 2.2.14, including Icefaces from 3.2.0 to 4.2.0.
I also upgraded Spring 3.2 to 5.1.2 and Spring Web Flow from 2.3.2.RELEASE to 2.5.1.RELEASE. The problem is, after the migration all Spring Web Flow are no longer invoked. When I click a button nothing happens. I take a look at the web console and every time I click on a button which should trigger the web-flow, I keep getting an http 403 error.
This is a snipet of my configuration:
<webflow:flow-executor id="flowExecutor">
<webflow:flow-execution-listeners>
<webflow:listener ref="facesContextListener"/>
<webflow:listener ref="icefacesFlowListener" />
</webflow:flow-execution-listeners>
</webflow:flow-executor>
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="flowRegistry" ref="flowRegistry"/>
<property name="order" value="0"/>
</bean>
<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />
<faces:flow-builder-services id="flowBuilderServices" development="true" />
<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" base-path="/WEB-INF/flows">
<webflow:flow-location-pattern value="**/*-flow.xml" />
</webflow:flow-registry>
The faces-config.xml is simple with only:
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
And the web.xml
<welcome-file-list>
<welcome-file>flow/welcome</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>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<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>
<servlet>
<servlet-name>flowDispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config />
</servlet>
<servlet-mapping>
<servlet-name>flowDispatchServlet</servlet-name>
<url-pattern>/flow/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>flowDispatchServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<resource-env-ref>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>
javax.enterprise.inject.spi.BeanManager
</resource-env-ref-type>
</resource-env-ref>
The main dependencies:
<spring-integration.version>5.1.0.RELEASE</spring-integration.version>
<spring-orm.version>5.1.2.RELEASE</spring-orm.version>
<spring-security-cas-client.version>3.0.8.RELEASE</spring-security-cas-client.version>
<spring-security.version>5.1.2.RELEASE</spring-security.version>
<spring.version>5.1.2.RELEASE</spring.version>
<spring.webflow.version>2.5.1.RELEASE</spring.webflow.version>
<spring-ws-core.version>3.0.4.RELEASE</spring-ws-core.version>
<javax.faces.version>2.2.14</javax.faces.version>
<icefaces-ace.version>4.2.0</icefaces-ace.version>
<validation-api.version>2.0.1.Final</validation-api.version>
I use Tomcat 8.5.
And a simple flow for tests:
<view-state id="start" view="welcome.xhtml">
<transition on="test" to="testView" />
</<view-state>
<view-state id="testView" view="test.xhtml"/>
The button in welcome.xhtml:
<h:form id="testForm">
....
<h:commandButton id="btnTest" class="button" value="Test" action="test"/>
</h:form>
welcome.xhtml is well rendered but clicking on the button, I get the 403 error.
Thanks for your help.
I finaly found the reason. Spring Security enables CSRF by default, which blocks POST request on my form. Disabled it solve the issue. I lost 5 days!!!!

Java config in Spring with AOP

This question is about Java config in Spring. Is it possible to replace the following declaration in Java code.
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/secure-app-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Where secure-app-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
...
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
<aop:aspectj-autoproxy />
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<context:component-scan base-package="com.abc.secure.service" />
<bean id="securityAspect" class="com.abc.secure.service.Secure" />
</beans>
You can very well do it by using WebApplicationInitializer(you dont need web.xml in this case)
Please see the post below:
How to configure Spring MVC with pure Java-based configuration?

Spring: not accept POST request under mvc:resources? how to fix that

I am using spring framework in my project,
Here is part of my web.xml:
<servlet>
<servlet-name>SpringMvcServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-context.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvcServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-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>
<error-page>
<error-code>404</error-code>
<location>/system/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/system/500.html</location>
</error-page>
And configure:
<mvc:resources mapping="/system/**" location="/WEB-INF/pages/system/" />
But I find so many error in my log, some request like this:
POST /index.php
POST /notexists.html
They were not exists in my server, so will call "/system/404.html", but the mvc:resources don't accept POST method, so it will return 500 Error.
How to fix that? or work around?
Thanks
First of all: I think you abuse the ResourceHttpRequestHandler when you try to use it for POST requests. -- And I am not sure that every thing works correct if you made this handler to handle POST requests.
<mvc:resources /> configure an instance of class org.springframework.web.servlet.resource.ResourceHttpRequestHandler. This has the super class WebContentGenerator and this super class has a property Set<String> supportedMethods.
So all what you need to do is:
<property name="supportedMethods">
<list>
<value>GET</value>
<value>HEAD</value>
<value>POST</value>
</list>
</property>
Unfortunately this requires that you configure the ResourceHttpRequestHandler by hand instead of using <mvc:resources />
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map>
<entry key="/system/**" value="myResourceHandler" />
</map>
</property>
<property name="order" value="100000" />
</bean>
<bean id="myResourceHandler" name="myResourceHandler"
class="org.springframework.web.servlet.resource.ResourceHttpRequestHandler">
<property name="locations" value="/WEB-INF/pages/system/" />
<property name="supportedMethods">
<list>
<value>GET</value>
<value>HEAD</value>
<value>POST</value>
</list>
</property>
<!-- cacheSeconds: maybe you should set it to zero because of the posts-->
</bean>
I have not proved this configuration, I have just written it down from what the ResourceBeanDefintionParser does.

configure BasicDataSource as bean in web.xml

I'm trying to configure org.apache.commons.dbcp.BasicDataSource as bean in web.xml under a tomcat project using tomcat 6. (it's red5 with tomcat, we can ignore that the main server is actually red5 because i actually run jsp files under port 5080 and don't connect to the red5 directly using RTMP protocol)
my web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/ j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>gamesisland-login-red5</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/[myapp]</param-value>
</context-param>
<listener>
<listener-class>org.red5.logging.ContextLoggingListener</listener-class>
</listener>
<filter>
<filter-name>LoggerContextFilter</filter-name>
<filter-class>org.red5.logging.LoggerContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoggerContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>rtmpt</servlet-name>
<servlet-class>org.red5.server.net.rtmpt.RTMPTServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/fcs/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/open/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/close/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/send/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rtmpt</servlet-name>
<url-pattern>/idle/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/streams/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/red5-web.properties" />
</bean>
<bean id="idDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>${db.driver}</value></property>
<property name="url"><value>${db.url}</value></property>
<property name="username"><value>${db.username}</value></property>
<property name="password"><value>${db.password}</value></property>
<property name="poolPreparedStatements"><value>true</value></property>
<property name="maxActive"><value>10</value></property>
<property name="maxIdle"><value>10</value></property>
</bean>
</web-app>
my red5-web.properties:
webapp.contextPath=/myapp
webapp.virtualHosts=*
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/dbname
db.username=user
db.password=pass
does tomcat automatically searches for WEB-INF/web.xml for configuration?
why don't I get any relevant errors to the creation of idDataSource ?
I really don't have any clue how to pinpoint or debug the problem.
any assistance would be greatly appreciated.
thank you!
kfir
I don't know nothing about Red5, but it seems like you trying to put Spring beans directly inside web.xml, which is wrong. You are suppose to create a separate Spring configuration file that will be picked up by Springs' ContextLoaderListener. First, add this to your web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Than create applicationContext.xml file under /WEB-INF:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/red5-web.properties" />
</bean>
<bean id="idDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>${db.driver}</value></property>
<property name="url"><value>${db.url}</value></property>
<property name="username"><value>${db.username}</value></property>
<property name="password"><value>${db.password}</value></property>
<property name="poolPreparedStatements"><value>true</value></property>
<property name="maxActive"><value>10</value></property>
<property name="maxIdle"><value>10</value></property>
</bean>
</beans>
Of course all the <bean/> declarations should go away from web.xml.
Second thought: looking at this document it seems like Red5 uses a file named red5-web.xml, please go through this documentation carefully.

Error creating bean with name : Scope 'request' is not active for the current thread

I have integrated SWF 2.2.1,Primefaces 2.2.1,JSF 2,Spring Security 3,Spring 3.1.0M1I and EhCache and AspectJ and Castor.
I have defined beans for castor in my app-config.xml like
<bean id="oXMapper" class="com.abc.xyz.util.OXMapper">
<property name="unmarshaller" ref="unmarshaller" />
<property name="marshaller" ref="marshaller" />
<property name="acordRequest" ref="acordRequest" />
<property name="acordResponse" ref="acordResponse" />
</bean>
<bean id="unmarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation"
value="classpath:/templates/mapping/ACORD_Response_Mapping.xml" />
</bean>
<bean id="marshaller" class="org.springframework.oxm.castor.CastorMarshaller">
<property name="mappingLocation"
value="classpath:/templates/mapping/ACORD_Request_Mapping.xml" />
</bean>
<bean id="acordRequest" class="com.abc.xyz.cate.domain.ACORD">
<property name="insuranceSvcRq" ref="insuranceSvcRq" />
<property name="signonRq" ref="CltSearch_signonRq" />
</bean>
I have a search page from where I am building the parameters like
<h:panelGrid>
<h:selectOneRadio id="#{msg.srchType}" value="#{acordRequest.insuranceSvcRq.com_csc_ClientSearchRq.com_csc_SearchInfo.com_csc_SearchCriteria.com_csc_ClientSearch.com_csc_SearchNameByType}">
<f:selectItem itemLabel="#{msg.exact}" itemValue="E" id="#{msg.exact}" />
<f:selectItem itemLabel="#{msg.phonetic}" itemValue="S" id="#{msg.phonetic}" />
<f:selectItem itemLabel="#{msg.truncated}" itemValue="P" id="#{msg.truncated}" />
</h:selectOneRadio>
</h:panelGrid>
Using Spring Webflow, I am calling the OXMapper functions and passing the ACORD(hierarchical structural as it is used to build xml) object to it. This OXMapper class is responsible for marshalling and unmarshalling of the object and xml respectively.
Now the problem is whenever I am searching again on search page , old values automatically populates inside the fields.
So I tried changing the scope to "Request".
<bean id="acordRequest" class="com.abc.xyz.cate.domain.ACORD"
scope="request">
<property name="insuranceSvcRq" ref="insuranceSvcRq" />
<property name="signonRq" ref="CltSearch_signonRq" />
</bean>
After changing the scope I get the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oXMapper' defined in ServletContext resource [/WEB-INF/config/app-config.xml]: Cannot resolve reference to bean 'acordRequest' while setting bean property 'acordRequest'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'acordRequest': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
My web.xml is as follows
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/config/web-application-config.xml
</param-value>
</context-param>
<error-page>
<error-code>500</error-code>
<location>/error.xhtml</location>
</error-page>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
<param-value>1</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/springsecurity.taglib.xml</param-value>
</context-param>
<!-- Enables Spring Security -->
<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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/certs/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
My faces-config.xml has nothing as such
<faces-config 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-facesconfig_2_0.xsd"
version="2.0">
<application>
<!-- <message-bundle>JsfMessageResources</message-bundle> -->
</application>
<!-- JSF 2.0 Version of this faces-config.xml file -->
If you are not using Spring MVC, in order to use the request scope, you must reference the RequestContextListener in your web.xml:
f you use a Servlet 2.4+ web container, with requests processed outside of Spring's DispatcherServlet (for example, when using JSF or Struts), you need to add the following javax.servlet.ServletRequestListener to the declarations in your web applications web.xml file:
<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>
Quote from docs.

Resources