Blackboard Building Blocks: Spring MVC Configuration 404 error - spring

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.

Related

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

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.

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?

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