How applicationcontext.xml is interpreted in struts and spring - spring

i have one question on applicationcontext.xml...
when web.xml is interpreted by server(tomcat or whatever)..does it first see applicationcontext.xml or struts.xml
(Or) does it first see whether the struts.xml is there and then interpret applicationcontext.xml and then come back to struts.xml and include applicationcontext.xml environment into struts.xml and then interpret the struts.xml
i would like to know how the flow goes.
i am using struts2 and spring 3 framework...
Thank you all..

Consider the following 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">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>/index.action</welcome-file>
</welcome-file-list>
</web-app>
Filters are initialised in order of occurrence. So most definitely struts.xml is read before applicationContext.xml however if reversed the opposite would be true. It is part of the servlet spec and explicitly stated here: http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html
If however you used a servlet to access a resource, it would be initialised after the filters and the order can be controlled by the servlets load-on-startup element.

Related

Spring OAuth2 resource classes not getting called

In reference to the below questions asked on StackOverflow, I have included a class
annotated with #Configuration, #EnableResourceServer and #EnableWebSecurity.
The code is building fine but the control is not going in this class which have been annotated the aforementioned way.
Do I need resource server with Spring Security OAuth2?
I checked that Security filters were disabled in my web.xml. Now, I have enabled them. Even though I am not getting the intended result when I hit my request, I think the initial issue is fixed.
That issue got solved but now I am facing another issue:
HTTP Status 500 - Failed to evaluate expression 'ROLE_USER'
root cause: org.springframework.expression.spel.SpelEvaluationException: EL1008E: Property or field 'ROLE_USER' cannot be found on object of type 'org.springframework.security.web.access.expression.WebSecurityExpressionRoot' - maybe not public?
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">
<display-name>hk-pensions</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/*.xml</param-value>
</context-param>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 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>
</filter-mapping>

My servlet stopped receive post params after adding CXF web service to the project

Good day, I created simple DynamicWebProject containing servlet Capture extending HttpServlet which overrides method doPost. When I sent a post request to this servlet it successfuly retrieved all posted parameters until I added simple Apache CXF Web Service. The CXF web service works but since I added it my servlet Capture isn't able to receive any posted parameters. When I post data to URL http://x.x.x.x:8080/capture the Capture.doPost method is called but no parameters are passed to it. When I comment out the listener tag it starts work again. Please could you advise why is this happening and how can I fix it? Many thanks in advance. Vojtech
This is my 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>MyApp</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/cxf.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Capture</servlet-name>
<servlet-class>myapp.servlet.Capture</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Capture</servlet-name>
<url-pattern>/capture</url-pattern>
</servlet-mapping>
</web-app>
And the cxf.xml file:
<?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:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:endpoint id="decodeWS" implementor="myapp.ws.decoder.DecoderServiceImpl" address="/decode">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
</beans>
EDIT: I resolved this issue by changing order of servlet mappings. If CaptureParts is on the first place then it works. But I still don't understand why the order matters.
<servlet-mapping>
<servlet-name>CaptureParts</servlet-name>
<url-pattern>/captureParts</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
You have
<param-value>WEB-INF/cfx.xml</param-value>
Should it be cxf.xml instead?

Spring DispatcherServlet context instantiation error in liferay 6.1.1

I'm in the process of migrating the liferay version of my webapp from 6.1.0 to 6.1.1 (using the 6.1.1-ga2 version from liferay patchers community and have a little problem with my webservices that where previously working.
I use the PortalDelegateServlet to instantiate a spring DispatcherServlet.
The problem I have is that the spring context of my servlet (myWS-servlet.xml) is instantiate before the application context of the PortletContextLoaderListener ( also tried with the ContextLoaderListener from spring, same problem )
and, as my controllers use services from the principal application context (which is not loaded at the time the DispatcherServlet is instantiated), spring cannot autowired them.
Strange thing is that the problem is resolved if I redeploy my portlet.
Do you have any idea how I can fix this ?
my 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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>banner-portlet</display-name>
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-portlet.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://liferay.com/tld/theme</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-theme.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://liferay.com/tld/portlet</taglib-uri>
<taglib-location>/WEB-INF/tlds/liferay-portlet-ext.tld</taglib-location>
</taglib>
</jsp-config>
<servlet>
<servlet-name>liferayWSdispatcher</servlet-name>
<servlet-class>com.liferay.portal.kernel.servlet.PortalDelegateServlet</servlet-class>
<init-param>
<param-name>servlet-class</param-name>
<param-value>org.springframework.web.servlet.DispatcherServlet</param-value>
</init-param>
<init-param>
<param-name>sub-context</param-name>
<param-value>rest-api</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>liferayWSdispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>com.liferay.portal.spring.context.PortletContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</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>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- Instruct Mojarra to utilize JBoss-EL instead of the EL implementation
provided by the servlet container. -->
<!-- was used only for admin portlets but make calendar portlet crash
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
-->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<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>
</filter-mapping>
<listener>
<listener-class>com.liferay.faces.portal.listener.StartupListener</listener-class>
</listener>
<!-- MyFaces will not initialize unless a servlet-mapping to the Faces Servlet
is present. -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>portalContextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-velocity-tool.xml</param-value>
</context-param>
my applicationContext.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: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-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">
<context:component-scan base-package="be.maximede">
<context:exclude-filter type="regex" expression="be.maximede.webservice.*"/>
</context:component-scan>
my myWS-servlet.xml
<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">
<context:component-scan base-package="be.maximede.webservice"/>
<mvc:annotation-driven />
I know this thread is over a year old. But I wanted to help save people some trouble. My coworkers and I spent a week trying to figure this out why we can't load spring services before portlet controllers using spring and PortalDelegateServlet + DispatcherServlet.
It's somewhat but not directly related to the Issue http://issues.liferay.com/browse/LPS-29103 as the other poster commented. It does have to do with the way Servlets were initialized in liferay and how Liferay handles web.xml rewrite.
Liferay rewrites all your listeners defined within web.xml and puts them into a context param likes this:
<context-param>
<param-name>portalListenerClasses</param-name>
<param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener</param-value>
</context-param>
and then creates its own listener (or not shown, a PluginContextListener):
<listener>
<listener-class>com.liferay.portal.kernel.servlet.SecurePluginContextListener</listener-class>
</listener>
This SecurePluginContextListener then loads up the context and wires things up. The problem is that sometimes, SecurePluginContextListener will initialize PortalDelegateServlet with the Web Application Context first and then it moves on to the init methods within the portalListenerClasses. So any AutoWired stuff within the portlet controller is missing all their dependencies (services from the application context).
In order to get around this, we ditched declaring PortalDelegateServlet within the web.xml and created a custom ServletContextListener that would new up a PortalDelagateServlet and ServletConfig, passing in the same parameters to spring's DispatcherServlet. The reason why this works is because, we let Liferay do all the loading within portalListenerClasses. The rewritten web.xml would look like this:
<context-param>
<param-name>portalListenerClasses</param-name>
<param-value>com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener,org.springframework.web.context.ContextLoaderListener, com.domain.CustomContextListener</param-value>
</context-param>
And CustomContextListener would implement the methods in ServletContextListener.
Within CustomContextListener's contextInitialized(...) method, we just programmatically create the same ServletConfig (An inner class that implements ServletConfig) we had inside the web.xml. We then create a pds = new PortalDelegateServlet() and call pds.init(customServletConfig)
For Liferay 6.1.1 this is a known issue:
http://issues.liferay.com/browse/LPS-29103

How can I use boolean parameters from application.properties in spring security context configuration xml file?

I am trying to use a boolean parameter from my application.properties in my spring-security configuration xml file.
I don't know why I can use not-boolean parameters, but I get an error for boolean.
How can I use boolean parameters?
Here is my application.properties:
JDBC_CONNECTION_STRING=jdbc:mysql://localhost:3306/schema?user=username&password=password
protocol=http
USE_SECURE=false
My spring-security.xml is:
< remember-me user-service-ref="internalUserDetails" data-source-ref="dataSource" key="this-is-my-key02203452416fw" use-secure-cookie="${USE_SECURE}" />
...
but I get this error:
cvc-datatype-valid.1.2.1: '${USE_SECURE}' is not a valid value for 'boolean'
I have also tried to set USE_SECURE=False but I get the same error again.
How can I use boolean parameters in the spring security configuration xml file?
Here is my web.xml:
<web-app 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"
version="3.0" >
<display-name> Name-MyApp</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Servlets -->
<servlet>
<servlet-name>MyApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlets Mappings -->
<servlet-mapping>
<servlet-name>MyApp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/servlet-context.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<!-- Filters -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>MyApp</servlet-name>
</filter-mapping>
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</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>
</web-app>
Looks that instead the value the key '${USE_SECURE}' is being passed. I come across similiar issue when I wanted to inistiate Boolean
<bean id="flag" class="java.lang.Boolean">
<constructor-arg value="${FLAG}"/>
</bean>
It works ok with the 'property', so i solved my case in other way. I am not sure if it is a spring bug?
The xsd schema definition of the security namespace only allows boolean values in the use-secure-cookie attribute. If you don't specify one of the allowed literals ("true" or "false"), your xml won't pass the schema validation, and won't get even parsed.
So if you use the security namespace configuration, you won't be able to use external properties to set this value. To prove my point, here is the relevant code snippet from RememberMeBeanDefinitionParser.parse():
String useSecureCookie = element.getAttribute("use-secure-cookie");
if (StringUtils.hasText(useSecureCookie)) {
services.getPropertyValues().addPropertyValue(
"useSecureCookie", Boolean.valueOf(useSecureCookie));
}
As you can see the attribute is straight away converted to boolean, so no mechanism is given any chance to further process the value.
I'm not completely sure, but chances are that this could be fixed by simply relaxing the xsd to allow any string value, and pass that value to the bean definition (services above) without converting it to boolean. Then a PropertyPlaceholderConfigurer could later resolve the given value if it happens to be a property placeholder.
If you want to give it a try, feel free to open a ticket in the Spring Security issue tracker.

RESTEasy Asynchronous HTTP with Spring MVC

Is there any handy way to use RESTEasy Asynchronous HTTP support (in my case on Tomcat 6) in conjunction with the Spring MVC framework. I've found useful articles on using RESTEasy with Spring, but none that cover asynchronous support, which appears to be a bit of a thorn at present, due to requring a different Servlet class depending on the container (Tomcat6CometDispatcherServlet for Tomcat, for example).
Thanks,
FB
I have created a sample app using Comet, Bayeux, Java, Maven and a Raphael JS frontend and wrote a blog post about it, you can use it as a base for your app, just wrapping the current service code in REST.
http://geeks.aretotally.in/thinking-in-reverse-not-taking-orders-from-yo
Hopefully it will help you.
For anybody interested, I ended up having to use the Tomcat6CometDispatcherServlet in preference to the Spring DispatcherServlet to get my application working.
I still have the Spring ContextLoaderListener in place to create the various beans within my Application Context, but have to use less than ideal means of accessing these from within my Controller classes, which are now JAX-RS annotated rather than Spring MVC annotated. (There are various articles a quick Google will uncover on accessing the Spring context programmatically.)
Here's a cleaned up version of my web.xml (nothing earth-shattering, but perhaps it will have some useful hints for somebody!):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>myapp</display-name>
<description>My App</description>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myapp.root</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>TrustedIPFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>TrustedIPFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>PollServlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.Tomcat6CometDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PollServlet</servlet-name>
<url-pattern>/poll/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/WEB-INF/jsp/uncaughtException.jsp</location>
</error-page>
</web-app>

Resources