After Spring framework upgrade from 3.2.9 to 5.3.22 and URL ending with .html stop working - spring

I have one application that is using Spring framework version 3.2.9.RELEASE and upgraded to 5.3.22 and With this, I have not made any configuration changes so far.
My DispatcherServlet.xml and all the web.xml configurations are as is.
But before this upgrade, I have a controller with #RequestMapping("/ssoLogin") and if I use the URL "ssoLogin.html", it was able to find the controller, but after this upgrade it is not able to do so.
Below is my web.xml dispatcher server config
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
<url-pattern>/auth/*</url-pattern>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
Below is the view resolver configuration
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
<!--To maintain HTTPS state -->
<property name="redirectHttp10Compatible" value="false" />
</bean>
Till now no config change and the URL ending with .html extension was working fine and after upgrade it is not working and getting 404 not found error in browser.

Thank you #M. Deinum
Your comment helped me.
To solve this problem, I went though the below links
https://github.com/spring-projects/spring-framework/issues/24179
https://github.com/lamsfoundation/lams/commit/7ff6d4b34cd71ac45741cb7c8d0c3ef6909eadf4
https://github.com/spring-projects/spring-framework/issues/23915#issuecomment-563987147
And based on this I made below change in my dispatcher-servlet.xml file
<mvc:annotation-driven>
<mvc:path-matching suffix-pattern="true" />
</mvc:annotation-driven>
And this has solved my problem.

Related

Blackboard Building Blocks: Spring MVC Configuration 404 error

I am using Spring MVC in my building block.
I am getting java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet error when I check in blackboard logs and UI is displaying following error message -
The specified resource was not found, or you do not have permission to access it.
My web.xml config is -
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</spring>
My view resolver config is -
<bean>
<bean id="primaryViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
My permission config in web.xml is -
<permission type="java.lang.reflect.ReflectPermission" name="suppressAccessChecks" />
<permission type="java.lang.RuntimePermission" name="accessDeclaredMembers" />
<permission type="java.lang.RuntimePermission" name="createClassLoader" />
<permission type="java.lang.RuntimePermission" name="setContextClassLoader" />
<permission type="java.io.FilePermission" name="${java.home}/lib/*" actions="read" />
You could include spring-beans and spring-context jars in your library. Also, the necessary jars might be already in your classpath but possibly they are not deployed on tomcat.
Be sure you are putting your JSP at the top level of your Building Block. Most often this error is caused by the dispatcher not being able to fine the jsp to render. If it is not at the top-level, just change your prefix property to point to the appropriate directory ().
Check https://github.com/blackboard/spring-b2-example for a very basic example to start with.

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)

Bean Context in 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.

Spring ReloadableResourceBundleMessageSource configuration

I develop a simple Spring application which is my university task. There are 3 configuration files: web.xml, core-context.xml, dispatcher-servlet.xml and 1 file with default properties which is called messages.properties and is located in /WEB-INF/ folder.
In my application I have the following configuration of ReloadableResourceBundleMessageSource and it works fine:
core-context.xml
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames" value="/WEB-INF/messages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:core-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
But it turned out that my task instruction says that I should configure ReloadableResourceBundleMessageSource bean in dispatcher-servlet.xml. The problem is that whenever I remove the above configuration from core-context.xml and put it in dispatcher-servlet.xml my locals are no longer displayed.
Could you explain to me why the problem occurs?
What is a difference between putting bean configuration inside core-context.xml and dispatcher-servlet.xml?
You have not posted your dispatcher-servlet.xml but I believe it is not being initialized by the spring container because it is not declared anywhere. If you must have another file called dispatcher-servlet.xml as you specify then you can just import it in your core-context.xml. This should solve your problem.

Spring, Need to use a a bean declared in a ApplicationContextFactory servlet, in a DispatcherServlet

i have a web.xml with these 2 servlet:
<servlet>
<servlet-name>ApplicationContextFactory</servlet-name>
<servlet-class>com.bamboo.common.factory.ApplicationContextFactory</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
AND
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
I need to use these bean declared on the ApplicationContextFactory:
<bean id="**catalogFacadeTarget**" class="com.bamboo.catW3.business.impl.CatalogFacadeImpl">
<property name="categoryDAO"><ref local="categoryDAOTarget"/></property>
<property name="containerDAO"><ref local="containerDAOTarget"/></property>
<property name="productDAO"><ref local="productDAOTarget"/></property>
<property name="productOptionDAO"><ref local="productOptionDAOTarget"/></property>
<property name="productStatusDAO"><ref local="productStatusDAOTarget"/></property>
<property name="userDAO"><ref local="userDAOTarget"/></property>
</bean>
in the dispatcher-servlet like this:
<bean name="welcome"
class="com.bamboo.catW3.business.impl.Welcome">
<property name="successView">
<value>welcome</value>
</property>
<property name="catalogFacadeImpl"><ref local="**categoryDAOTarget**"/> </property>
</bean>
Is it posible some how? Thank you!
You can't share contexts between servlets.
If you need to share beans, then you need to move the shared beans out of the ApplicationContextFactory servlet's context and into the root webapp context, using a ContextLoaderListener declared in web.xml. Both servlets will then be able to use the beans defined in that root context.
(I'd give you a link, but springsource.org seems be down at the moment).

Resources