Bean Context in Spring - spring

The application works perfectly with the following config files:
My Web.XML is as follows
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring/mvc-dispatcher-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>*.do</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/classes/spring/spring-context.xml,
/WEB-INF/classes/spring/spring-security.xml
</param-value>
</context-param>
<!-- 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 mvc-dispatcher-servlet
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<context:component-scan base-package="biz.canisrigel.slapMe" />
<!-- enable autowire -->
<context:annotation-config />
My spring-context.xml is
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<context:component-scan base-package="biz.canisrigel.slapMe" />
<!-- enable autowire -->
<context:annotation-config />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost/slapMe" />
<property name="username" value="root" />
<property name="password" value="adminadmin" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="biz.canisrigel.slapMe.bean" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="biz.canisrigel.slapMe.mapper" />
</bean>
I couldn't run spring security properly cause earlier spring-context.xml was the xml config file for dispatcher servlet for MVC. So I moved spring-context to contextConfigLocation. But then I had to provide something to dispatcher servlet.
My problem is that mvc-dispatcher-servlet.xml and spring-context is having same data. If I remove mvc-dispatcher its an error. If I don't place the contents of mvc-dispatcher in spring context then also error occurs.
Where am I going wrong in my understanding of concepts.

A few things:
Your web.xml looks correct
The InternalResourceViewResolver should only exist in your mvc-dispatcher-servlet.xml since it is directly related to MVC -- remove it from your spring-context.xml
You can have context:component-scan in both configuration files, but they should be scanning different packages. The one in your servlet xml will generally be component scanning your controller packages (and anything else directly related to MVC), and the one in your parent spring context xml will generally be scanning your services, DAOs, etc. In general, your component scan packages should be very specific; you should never point it towards the base package of your entire application!
You can remove context:annotation-config -- it is redundant if you have context:component-scan

Your MVC context should have only configuration related to MVC which generally includes ViewResolvers, FileUpload, PropertyFiles, Message/Theme Resolvers etc. Your applicationContext will have beans related to DAO, Service and other utils. The security file should have security configuration. To understand better and to know good/recommended practices, check out the spring greehouse code.

Related

#Transaction at Service layer not working on DAO layer in spring

I am using #Transactional (org.springframework.transaction.annotation) at the service method from where I call the DAO layer to fetch data from DB.
However, I am getting following error
org.hibernate.HibernateException: No Session found for current thread
on
sessionFactory.getCurrentSession()
I have added package scanning to different files as suggested by other posts.Still unable to get the error.
Please help.Thanks a million in advance.
Following are the files I have used.
applicationContext.xml
<mvc:annotation-driven />
<context:annotation-config/>
<context:component-scan base-package="com.BASE_PCKG"></context:component-scan>
spring-servlet.xml
<mvc:annotation-driven />
<context:component-scan base-package="com.BASE_PCKG.SUB_PCKG.web"></context:component-scan>
Web.xml
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext.xml</param-value>
</context-param>
....
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Also I have configured the transaction manager in applicationContext file as :
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" primary="true">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
Add #Transactional on daoImpl class and Add transaction manager in configuration file:
<tx:annotation-driven/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
Calling the method via proxy would help and fix the issue.
Calling the same method from same class would not help transaction work.

Spring MVC REST + Spring Security + Basic Authentication

Environment :
Spring 4.1
Spring security 4.0
Issue :
I am developing a simple REST service using Spring 4.1. And using Spring security for authentication purpose.
I am using HTTP Basic Authentication.
The issue is , basic authentication is not working even after all configuration is correct.
I am using postman to send a request to server.
REST client can call the REST controller method without Authorization header.
The method gets executed successfully without any authentication error.
Since I am using Tomcat 6 , I am not using servlet 3.0 features , so web.xml does exist.
The method level security has been implemented using #Secured annotation on REST controller layer.
Can anybody please help as to where I am going wrong ?
Code :
web.xml :
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet-security.xml</param-value>
</context-param>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</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>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
</web-app>
mvc-servlet-dispatcher-security.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<http use-expressions="true" create-session="stateless">
<http-basic/>
<csrf disabled="true"/>
</http>
<global-method-security secured-annotations="enabled"/>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="XYZ" password="12345" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
mvc-dispatcher-servlet.xml :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Specifying base package of the Components like Controller, Service, DAO -->
<context:component-scan base-package="org.ngo" />
<!-- Getting Database properties -->
<context:property-placeholder location="classpath:application.properties"/>
<mvc:annotation-driven/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan" value="org.ngo.abhishek.entity"></property>
</bean>
<!-- Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
The REST controller :
#RestController
#RequestMapping("/abhishek")
public class AbhishekController {
#Autowired
private AbhisheskService abhishekService;
#RequestMapping(method=RequestMethod.POST,consumes="application/json")
#Secured("ROLE_USER")
public ResponseEntity<Boolean> getUserById(#RequestBody List<AbhishekDTO> abhishekDtoList) {
boolean flag = this.abhishekService.createAbhishek(abhishekDtoList);
return new ResponseEntity<Boolean>(flag, HttpStatus.OK);
}
}
I tried your setup and it worked for me. Since you did not provide all of your code, my best guess is either the component scan of your controller for Spring Security is not happening or maybe your browser is caching and sending the Basic Auth credentials without you realizing it.
After getting a clue from Stiletto , I removed #Secured("ROLE_USER") and used expression based security check. It worked (using intercept url). So the issue was with where #Secured has been placed.
Since #Secured was in dispatcher servlet context (child context as per Spring philosophy) and spring security scope was in applicationContext (parent context) , the spring security was getting ignored.
Putting <security:global-method-security secured-annotations="enabled"/> in mvc-dispatcher-servlet.xml resolved the issue.
Similar question on SO : Spring MVC, Method level security

Not Rolling Back Spring Transaction From ZK

I am facing a problem while calling the service method written in Spring Sevice that is injected in MVVM in that method I am saving one object and after that doing some other value fatching method call that throw exception and I want that while throwing that exception my Transaction rollback my service method part are as under CeilingServiceIMPL:
CeilingSheet ceilingSheet = new CeilingSheet();
ceilingSheet.setFiscalYear(fiscalYear);
ceilingSheet.setStatus(ECeilingSheetStatus.NEW);
ceilingSheet = saveCeilingSheet(ceilingSheet).getResult();
CeilingCategory ceilingCategory1 = null;
try {
ceilingCategory1 = categoryQueryService.findCeilingCategoryByCode(
"01").getResult();
} catch (ObjectNotFoundException ex) {
throw new RequestException(1234, ceilingCategory1);
}
if RequestException throws , I am expecting that my record that I saved before also rollback. I have making the service Transaction by annotating as
#Transactional(rollbackFor = RequestException.class)
The bean is injected with
#WireVariable(ICeilingSheetService.NAME) private ICeilingSheetService ceilingSheetService;
When I tried this method to call from junit test case it rolling back fine , but when I integrate it with ZK zul page and View Model by autowired services it stop rolling back and even if my code throws RequestException my CeilingSheet are persisting.
My ZK web.xml is
<!-- Spring can be easily integrated into any Java-based web framework.
All you need to do is to declare the ContextLoaderListener in your web.xml
and use a contextConfigLocation <context-param> to set which context files
to load. If you don't specify the contextConfigLocation context parameter,
the ContextLoaderListener will look for a /WEB-INF/applicationContext.xml
file to load. Once the context files are loaded, Spring creates a WebApplicationContext
object based on the bean definitions and puts it into the ServletContext. -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-context.xml
</param-value>
</context-param>
<!-- LOGGER -->
<context-param>
<param-name>log4j-config-location</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<!-- Loads the Spring web application context -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- end of spring configuration -->
<description><![CDATA[My ZK Application]]></description>
<display-name>IFMIS User Interface</display-name>
<!-- //// -->
<!-- ZK -->
<listener>
<description>ZK listener for session cleanup</description>
<listener-class>org.zkoss.zk.ui.http.HttpSessionListener</listener-class>
</listener>
<servlet>
<description>ZK loader for ZUML pages</description>
<servlet-name>zkLoader</servlet-name>
<servlet-class>org.zkoss.zk.ui.http.DHtmlLayoutServlet</servlet-class>
<!-- Must. Specifies URI of the update engine (DHtmlUpdateServlet). It
must be the same as <url-pattern> for the update engine. -->
<init-param>
<param-name>update-uri</param-name>
<param-value>/zkau</param-value>
</init-param>
<!-- Optional. Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if you configure
a filter to post-processing the output, you might have to disable it. Default:
true <init-param> <param-name>compress</param-name> <param-value>true</param-value>
</init-param> -->
<!-- [Optional] Specifies the default log level: OFF, ERROR, WARNING, INFO,
DEBUG and FINER. If not specified, the system default is used. <init-param>
<param-name>log-level</param-name> <param-value>OFF</param-value> </init-param> -->
<load-on-startup>1</load-on-startup><!-- Must -->
</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>
<!-- [Optional] Uncomment it if you want to use richlets. <servlet-mapping>
<servlet-name>zkLoader</servlet-name> <url-pattern>/zk/*</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>
<!-- [Optional] Specifies whether to compress the output of the ZK loader.
It speeds up the transmission over slow Internet. However, if your server
will do the compression, you might have to disable it. Default: true <init-param>
<param-name>compress</param-name> <param-value>true</param-value> </init-param> -->
<!-- [Optional] Specifies the AU extension for particular prefix. <init-param>
<param-name>extension0</param-name> <param-value>/upload=com.my.MyUploader</param-value>
</init-param> -->
</servlet>
<servlet-mapping>
<servlet-name>auEngine</servlet-name>
<url-pattern>/zkau/*</url-pattern>
</servlet-mapping>
My application-context.xml
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/database.properties</value>
<value>/WEB-INF/msg-database.properties</value>
</list>
</property>
</bean>
<tx:annotation-driven />
<context:annotation-config />
<context:component-scan base-package="my.service" />
<import resource="hibernate-context.xml" />
My hibernat-context.xml
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass">
<value>${jdbc.driverClassName}</value>
</property>
<property name="jdbcUrl">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
<property name="minPoolSize" value="${jdbc.minPoolSize}" />
<property name="maxStatements" value="${jdbc.maxStatements}" />
<property name="testConnectionOnCheckout" value="${jdbc.testConnection}" />
</bean>
<!-- bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"> <value>${driverClassName}</value> </property>
<property name="url"> <value>${url}</value> </property> <property name="username">
<value>${username}</value> </property> <property name="password"> <value>${password}</value>
</property> </bean -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>my.domain.class</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="jadira.usertype.autoRegisterUserTypes">${jadira.usertype}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
Please advice ...
The first step in such cases is always to enable logging at level DEBUG for org.springframework.orm.hibernate4.HibernateTransactionManager. That will show you what Spring is doing and why.
For example, it will show you when it detects an exception and when it does a rollback or a commit. You can also set breakpoints in this code to see what is going on. It's pretty straightforward.
Knowing a bit about ZK, my guess is that you have new CeilingServiceIMPL() somewhere in the ZK code because you couldn't figure out how to inject Spring beans into a controller. This effectively renders all #Transactional useless.
You must get the bean from spring. Check out http://www.zkoss.org/product/zkspring and the documentation at Using Spring Variable Resolver how to wire beans with ZK.
I found the solution :
Reason : In My application we have the requirement to show the User messages based on the number thrown by the exception , for this we have a separate message-hibernate-context.xml file with seperate
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="messageSessionFactory" />
</bean>
and one is already with hibernate-context.xml
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
and the above both xml file called from my application-context.xml as
<import resource="hibernate-context.xml" />
<import resource="message-hibernate-context.xml" />
So after code thrown exception based on key thrown , my user-message bean trying to load separate Transaction Manager and old transaction committed and new Hibernate session starts that was going to rollback and since this is new Transaction so It does not found anything to rollback.
Once I removed other Transaction Manager it start working .
Thanks All for support...

Spring Themes not working with REST

I have been trying to solve this problem for several days now and I also couldn't find any posts in forums with a similar problem. I have Spring Theme working well when I have the servlet mapping url-pattern as *.html in the web.xml file. However, if I change the url-pattern in the web.xml file to forward slash, so that the default servlet handles all requests and that the URLs can look like REST URLs, then I use to get NO MAPPING error, which results in not able to display the css settings for web pages. The NO MAPPING warning that I get use to get is as follows:
WARN http-apr-8080-exec-6 (DispatcherServlet.java:947) - No mapping found for HTTP request with URI [/MyApp/themes/default.css] in DispatcherServlet with name 'spring'.
But upon the mapping issue being solved by adding to my Spring servlet configuration file:
<mvc:default-servlet-handler />
another problem has arisen: Now, upon the application being started and prior to any operations, the use of clicking the Theme choice prior to any REST operation works well. It all works fine displaying the correct Theme. In fact, if I go via the normal Controllers (without REST) and do non-REST operations, everything continues to work as normal and I can switch between Themes. However, upon going via REST, and upon clicking on a Theme and even though it returns the same view name as the normal Controller would return, I get the following error in the browser and strangely with no console (debug) messages being reported:
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/7.0.29
Here is my UPDATED web.xml files is:
<?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_2_5.xsd" version="2.5">
<display-name>LiveAppSpring</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>liveAppSpring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>liveAppSpring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
and my UPDATED Spring servlet configuration is:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
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">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<mvc:interceptors>
<beans:bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor">
<beans:property name="paramName" value="theme" />
</beans:bean>
</mvc:interceptors>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<!--
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
View Classes:
<beans:property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
-->
<!--
<beans:bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
-->
<!-- This attribute could also be added to viewResolver bean below...
<beans:property name="requestContextAttribute" value="requestContext"/>
-->
<beans:bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView" />
</beans:bean>
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/tiles.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- Application Message Bundle -->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basename" value="classpath:messages" />
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<beans:bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<beans:property name="defaultLocale" value="en"/>
</beans:bean>
<!-- Theme setup -->
<beans:bean id="themeSource" class="org.springframework.ui.context.support.ResourceBundleThemeSource">
<beans:property name="basenamePrefix" value="theme-" />
</beans:bean>
<beans:bean id="themeResolver" class="org.springframework.web.servlet.theme.CookieThemeResolver">
<beans:property name="defaultThemeName" value="default" />
</beans:bean>
<!--
The 2 bean declarations below are NOT compatible with 3.0.5 as it conflicts with the mvc tag library (as defined in header).
Work around is to have the mvc:interceptors tag declared as done near the top of this configuration file.
-->
<!--
<beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<beans:property name="paramName" value="lang" />
</beans:bean>
-->
<!--
<beans:bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<beans:property name="interceptors">
<beans:ref bean="localeChangeInterceptor" />
</beans:property>
</beans:bean>
-->
<context:component-scan base-package="com.liveapp.spring" />
</beans:beans>
And finally, my Theme properties files are location in
LiveAppSpring\src\main\resources
with the contents of all Theme properties files having the following pattern:
css=themes/default.css
AND to be safe, I have my css files duplicated in all 3 directories:
LiveAppSpring\src\main\webapp\resources
LiveAppSpring\src\main\webapp\resources\themes
LiveAppSpring\src\main\webapp\themes
Any directions would be appreciated.
I expect that /MyApp/themes/default.css should deliver default.css. But this is a resource file, and you mapped them by
<mvc:resources mapping="/resources/**" location="/resources/" />
So the right request url would be /MyApp/resources/default.css (assuming that the default.css is located in webapp/resources/default.css)

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.

Resources