Trying out Spring 3 MVC, Getting a page error - java

Trying to configure spring 3 MVC, here is what I did so far:
I added all the spring 3.0 libraries to my netbeans project.
My web.xml 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" 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">
<servlet>
<servlet-name>WebApplication1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WebApplication1</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Next I created a WebAppliation1-servlet.xml, also in my /web-inf folder:
<?xml version="1.0" encoding="UTF-8"?>
<!--
- DispatcherServlet application context for PetClinic's web tier.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
<!--
- The controllers are autodetected POJOs labeled with the #Controller annotation.
-->
<context:component-scan base-package="org.springframework.Hi"/>
<!--
- The form-based controllers within this application provide #RequestMapping
- annotations at the type level for path mapping URLs and #RequestMapping
- at the method level for request type mappings (e.g., GET and POST).
- In contrast, ClinicController - which is not form-based - provides
- #RequestMapping only at the method level for path mapping URLs.
-
- DefaultAnnotationHandlerMapping is driven by these annotations and is
- enabled by default with Java 5+.
-->
<!--
- This bean resolves specific types of exceptions to corresponding logical
- view names for error views. The default behaviour of DispatcherServlet
- is to propagate all exceptions to the servlet container: this will happen
- here with all other types of exceptions.
-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.springframework.web.servlet.PageNotFound">pageNotFound</prop>
<prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
<prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop>
</props>
</property>
</bean>
<!--
- The BeanNameViewResolver is used to pick up the visits view name (below).
- It has the order property set to 2, which means that this will
- be the first view resolver to be used after the delegating content
- negotiating view resolver.
-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="1"/>
<!--
- This bean configures the 'prefix' and 'suffix' properties of
- InternalResourceViewResolver, which resolves logical view names
- returned by Controllers. For example, a logical view name of "vets"
- will be mapped to "/WEB-INF/jsp/vets.jsp".
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" p:order="2"/>
</beans>
I then created a simple welcome.jsp in the folder /WEB-INF/jsp/welcome.jsp
I then created a package:
org.springframework.Hi
And I created a TestController.java file:
package org.springframework.Hi;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class TestController {
#RequestMapping("/")
public String welcomeHandler(){
return "welcome";
}
}
I wanted this to work w/o any file extensions, so I don't have to end my urls with xxx.htm etc.
So when I run the netbeans project I get the error:
type Status report
message Servlet WebApplication1 is not available
description The requested resource (Servlet WebApplication1 is not
available) is not available.
What exactly am I missing here?
Tomcat logs
Thanks for the feedback
My tomcat logs show this:
SEVERE: Servlet /WebApplication1 threw load() exception
java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:316)
at org.springframework.web.servlet.DispatcherServlet.<clinit>(DispatcherServlet.java:207)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

I'm asuming that error message you quoted was the error message the browser sees when it tries to access the application. This is because it didn't deploy properly.
You need to look through the web server startup logs, that will give you much more information as to why it didn't deploy.
edit: OK, that helps a lot... you need to add Apache Commons Logging to your classpath.

I used to encounter a similar problem... except it happened only when I try to run the Spring Web MVC app via the STS IDE (version 2.3.2). However, if I packaged as a WAR and deployed it to a running instance of tcServer or even Tomcat, the app worked just fine.
I ended up adding commons-logging and some other JARs to the server's launch configuration in STS IDE, in the User Entries section under the Classpath tab. This solved my problem. Why some JARs don't get added to the Java EE module dependency while running within STS, I don't still understand.
Hope this helps.

Related

Glassfish4 + EJB + Spring, deploy fails

I am upgrading an application from Java7 on Glassfish 3.1.2.2, to Java8 on Glassfish 4.1. The application is packaged as an ear file, containing a jar-file with remote EJBs and Spring beans, as well as a war-file with a couple of servlets and some webservices.
There are only some minor changes done to the actual application, compared to how it was with Glassfish 3.x, the total changes made are:
Built with Java8 instead of Java7.
Deployed on Glassfish 4.1 instead of 3.1.2.2
Newer version of Hibernate
Newer version of ActiveMQ (client)
I can't see any difference between the previous ear-file and the new one (except the abovementioned lib-jars), but still when I try to deploy I get errors like this for all my EJBs:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type SomethingLogic with qualifiers #Default
at injection point [BackedAnnotatedField] #Inject private com.my.application.server.service.SomethingServiceSession.somethingLogic
Where SomethingService is an EJB, SomethingLogic is a Spring bean.
My EJBs are defined like this:
#Stateless
#RolesAllowed("secure")
#Interceptors(SpringBeanAutowiringInterceptor.class)
public class SomethingServiceSession implements SomethingService {
#Inject
private SomethingLogic somethingLogic; //Spring bean
SomethingLogic is an interface.
I have a beanRefContext.xml containing:
<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.xsd">
<bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:applicationContext-glassfish.xml"/>
</bean>
</beans>
The EJB services are defined in glassfish-ejb-jar.xml, like this:
<ejb>
<ejb-name>SomethingServiceSession</ejb-name>
<ior-security-config>
<as-context>
<auth-method>USERNAME_PASSWORD</auth-method>
<realm>AD</realm>
<required>true</required>
</as-context>
</ior-security-config>
</ejb>
I have tried adding a beans.xml with the following content to the resources\META-INF folder of my EJB-project:
<?xml version="1.0"?>
<beans 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://jboss.org/schema/cdi/beans_1_0.xsd" />
No luck.
I have also tried adding #LocalBean to all my EJBs, also with no luck.
In addition, I have tried to disable CDI all together, using this command:
asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false
This actually allows my EJB services to be deployed, but I'm suspecting that it has the not so good side effect of my webservices not being discovered, so I want to be able to deploy with CDI enabled to rule this out.
Update:
I have tried changing #Inject with #Autowired in all my non-Spring-handled classes (EJBs, webservices and servlets). Now I get the same error for actual Spring beans. It seems that Glassfish will try to look for EJB beans when encountering #Inject, no matter where they occur.
Fixed my problem by adding bean-discovery-mode="none" to my various beans.xml files.
<?xml version="1.0"?>
<beans 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://jboss.org/schema/cdi/beans_1_2.xsd"
bean-discovery-mode="none" />

Why Spring RequestMapping not working without #Controller?

Sample code I have:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springDispatcher-servlet.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="myController" class="biz.tugay.springWebOne.MyController"/>
</beans>
MyController.java
package biz.tugay.springWebOne;
/* User: koray#tugay.biz Date: 08/07/15 Time: 15:25 */
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class MyController {
#RequestMapping(value = "/hello")
public String helloWorld(){
return "index.jsp";
}
}
Well, everything works fine with this code. However when I remove the
#Controller
from MyController class I will get:
HTTP ERROR 404
Problem accessing /hello. Reason:
Not Found
I am not using component-scan, I am using an xml based configuration. Why do I need the #Controller annotation?
from spring reference documentation here
The #Controller annotation acts as a stereotype for the annotated
class, indicating its role. The dispatcher scans such annotated
classes for mapped methods and detects #RequestMapping annotations
so #Controller is required to tell dispatcher to scan mapping in this class not only for component scan.
If you are using component scanning, Spring will not know where to scan for #RequestMapping without the #Controller annotation. If you would like to configure your requestmappings with XML, that should be able to be done similar to one of the answers here: #RequestMapping with XML
Your example will not work because the #Controller annotation is essentially the "entry point" telling the component scanner to scan this class, without #Controller all other spring controller annotations (eg. #RequestMapping) will be ignored.
I noticed that you pointed out that you are not using component-scan and you are using xml-based configuration, but in reality you are attempting to mix xml-based and annotation-based configuration for a single class, which will lead to very sloppy code. I would recommend removing your xml bean definition and using only the #Controller annotation and adding the component-scan tag in your xml to clean up your code.
If you decide you still want to do xml only configuration you should remove the #RequestMapping annotation and replace it with the following xml.
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<map>
<entry key="/hello" value-ref="myController"/>
</map>
</property>
</bean>
If you want to use Spring without annotations, so you can use a BeanNameUrlHandlerMapping to indicate the controller class to the Dispatcher. So, just add the following bean to your XML and you do not have to include the #Controller anymore:
<bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

JNDI name not found - how to use JNDI in WCM workflow plugin?

I'm using Rational Application Developer 8.5 to develop a custom workflow action plugin for IBM Web Content Manager (WCM) in WebSphere Portal 7.0.
The plugin needs to get a JDBC data source with JNDI, but all my attempts to do so produce this error:
javax.naming.NameNotFoundException: Name comp/env/jdbc not found in context "java:".
A data source named "jdbc/wcmbulletins" is defined in the WebSphere Application Server.
Here's the java code to get the data source:
javax.naming.InitialContext ctx=new javax.naming.InitialContext();
javax.sql.DataSource ds=(javax.sql.DataSource)ctx.lookup("java:comp/env/jdbc/wcmbulletins");
The RAD project contains the following XML files only. There's no "persistence.xml" or any other files I've seen mentioned in similar SO questions.
There are also some JSP files referenced by WCM JSP components. The JSP files have no connection with the plugin and don't use JNDI or JDBC.
ibm-web-bnd.xml:
<web-bnd
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
<virtual-host name="default_host"/>
<resource-ref name="jdbc/wcmbulletins" binding-name="jdbc/wcmbulletins"/>
</web-bnd>
ibm-web-ext.xml:
<web-ext
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd"
version="1.0">
<jsp-attribute name="reloadEnabled" value="false"/>
<jsp-attribute name="reloadInterval" value="10"/>
<reload-interval value="3"/>
<enable-directory-browsing value="false"/>
<enable-file-serving value="true"/>
<enable-reloading value="true"/>
<enable-serving-servlets-by-class-name value="true"/>
</web-ext>
plugin.xml:
<plugin id="com.company.wcm.CompanyWCMPlugins"
name="Company WCM Plugins"
version="1.0.0"
provider-name="Company Name Australia">
<extension
point="com.ibm.workplace.wcm.api.CustomWorkflowActionFactory"
id="CompanyWorkflowActionFactory">
<provider class="com.company.wcm.workflow.CompanyWorkflowActionFactory"/>
</extension>
</plugin>
web.xml:
<web-app id="WebApp_ID" 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">
<display-name>CompanyWCM_JSPs</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<resource-ref id="ResourceRef_1377568155870">
<description/>
<res-ref-name>jdbc/wcmbulletins</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
What do I need to make the JNDI lookup work?
What happens if you change the code to bypass the resource reference and use the name jdbc/wcmbulletins instead?
Also - at what scope is the DS defined? If at cluster level try the name cell/persistent/jdbc/wcmbulletins and see what you get.
Lastly - there is always the WebSphere naming trace. You can enable them via Naming=all, re-run your app, and check trace.log for insight as to what might be going on.
Hope this helps,
ScottH
From my experience, wcm plugins are somewhat independent from the web-application they are contained in (they are more related to OSGI or so). For example during server startup plugins are instantiated, before the web-application itself is, so it might not even be possible to reliably lookup resources from the web-app.

Spring MVC 404 error [duplicate]

This question already has answers here:
Why does Spring MVC respond with a 404 and report "No mapping found for HTTP request with URI [...] in DispatcherServlet"?
(13 answers)
Closed 5 years ago.
I'm going crazy and can't understand what the problem is:
I have the following structure:
SpringMVC
+WebContent
-web-inf
-web.xml
-springMVC-servlet.xml
-index.jsp
-security
-login.jsp
web.xml
<display-name>springMVC</display-name>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/index.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
springMVC-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans 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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans">
<context:annotation-config/>
<context:component-scan base-package="com.vanilla.springMVC"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
My Controller:
package com.vanilla.springMVC;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.portlet.ModelAndView;
#Controller
public class DefaultController {
#RequestMapping(value="/index.html", method=RequestMethod.GET)
public ModelAndView index(){
ModelAndView mv = new ModelAndView("index");
return mv;
}
#RequestMapping(value="/login.html", method=RequestMethod.GET)
public ModelAndView loginPage(){
ModelAndView mv = new ModelAndView("/security/login");
return mv;
}
}
I have no problem to navigate to /index.html
http://localhost:8080/SpringMVC/index.html
works perfect.
however when I'm navigating to
http://localhost:8080/SpringMVC/login.html
i have 404 error.
HTTP Status 404 - /SpringMVC/login.jsp
type Status report
message /SpringMVC/login.jsp
description The requested resource (/SpringMVC/login.jsp) is not available.
I don't want to move login.jsp on the same level as index.jsp, but why do I have this problem?
I'll just add this in here, because it solved my 404 issue. It turned out my problem was the url-mapping value in web.xml. Using Spring WebMVC version org.springframework:spring-webmvc:4.1.6.RELEASE
I was using the following (which didn't work):
<url-pattern>/rest</url-pattern>
I should've been using the following value (which works):
<url-pattern>/rest/*</url-pattern>
or
<url-pattern>/</url-pattern>
Reference: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
HTTP 404 means that the resource is not found.
This means the controller or a direct accessed resource (like a CSS file) is not found
It does NOT mean that the JSP referred in the controller is not found (this would be a 500 Internal Server Error)
HTTP Status 404 - /SpringMVC/login.jsp
It looks like that you send a HTTP request /SpringMVC/login.jsp but your controller method is bound to .html, so you need to change your HTTP request to /SpringMVC/login.html
Because of the name (login) may your Spring Security configuration is not correct.
create a folder under WEB-INF "jsps" for all your views, and under "jsps" a "security" folder for your case.
NOTICE: Moving the JSP files into WEB-INF, you can prevent direct access on these files. It is needed for application security. Think about a situation, in which your JSPs gives personal informations about your customer and the access has to be granted/checked by your controller. If your JSPs are existing out of WEB-INF, they are accessible with a request directly on them.
configure your view resolver like this:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsps"/>
<property name="suffix" value=".jsp"/>
</bean>
next, put your login JSPs into the "WEB-INF/jsps/security"
and return "security/login" from your loginPage.
Now, the view resolver searchs for the views under "WEB-INF/jsps". Because your method return "security/login", the view resolver expects a directory under jsps called "security" and a JSP file under this, which is called "login.jsp" (suffix = jsp)
I suspect that ModelAndView mv = new ModelAndView("/security/login"); is where the problem is. Make sure you have a directory 'security' folder in your root directory and it contains a login.jsp file. Or try moving the security folder inside WebContent
Provide the contextConfigLocation init parameter of your DispatcherServlet
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springMVC-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I am using Spring MVC with eclipse and a MacOS X system and encountered a 404 error when controller returning the correct jsp name. I later figured out that the problematic jsp file has no x(execution) right on the file system. I then `chmod +x some.jsp' and the issue is resolved.
Adding this ans here just in case someone else faces the same issue.
My app was working fine earlier, then I upgraded Spring version and in the process also upgraded spring-security version. When I tried to access my login html page I was facing this issue. I had made all the necessary configurations changes because of the change of spring-security version from 3 to 4. I referred to this link and it was very helpful.
I was facing this problem because of the below configuration in my web-servlet.xml file
<mvc:resources mapping="/app/*.html" location="/app/*.html" cache-period="0"/>
<mvc:resources mapping="/app/**/*.html" location="/app/**/*.html" cache-period="0"/>
It worked after I modified both location values to "/app/". It seems like newer version of spring matches either the whole string or checks if the requested location starts with the location value configured above.
I found the below code in org.springframework.web.servlet.resource.PathResourceResolver:
if (locationPath.equals(resourcePath)) {
return true;
}
locationPath = (locationPath.endsWith("/") || locationPath.isEmpty() ? locationPath : locationPath + "/");
if (!resourcePath.startsWith(locationPath)) {
return false;
}
The second if condition was evaluating to false in my case and hence the 404 HTTP response
Another tip, if you face such error try enabling highest level of springframework logging. You might get to know the error reason from there.
This answer may be outdated for the above question, but it will help others who are just starting with spring.
I was also struggling with 404 WEB-INF/welcome.jsp page not found error.
Here issue is with ModelAndView import
Replace
import org.springframework.web.servlet.ModelAndView;
With
import org.springframework.web.portlet.ModelAndView;

404 with spring 3

hi
I am going through my first lessons with spring 3.I created a dynamic web app in eclipse with the following structure.
spring3mvc \src\my.spring.HelloWorldController.java
\WebContent
|
|-----WEB-INF\jsp\hello.jsp
|-----index.jsp
|-----WEB-INF\web.xml
|-----WEB-INF\spring-servlet.xml
|-----WEB-INF\lib\...*.jar files
I created the spring-servlet.xml as below
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/context
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="my.spring" />
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp">
<property name="contentType" value="text/html; charset=utf-8" />
</bean>
</beans>
and coded the controller
package my.spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class HelloWorldController {
#RequestMapping("/hello")
public ModelAndView helloWorld() {
String message = "Hello World, Spring 3.0!";
return new ModelAndView("hello", "message", message);
}
}
index.jsp has a link to hello view
<html>
<body>
Say Hello
</body>
</html>
finally in hello.jsp I have put
<html>
<body>
${message}
</body>
</html>
My web.xml has
<display-name>Spring3MVC</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
When I run the app on Tomcat6 server( thru eclipse),I can see the index page at
http://localhost:8080/Spring3MVC/ .It displays the link to hello page.When I click on it(http://localhost:8080/Spring3MVC/hello.html),I get a 404 error.
message /Spring3MVC/hello.html
description The requested resource (/Spring3MVC/hello.html) is not available.
Any idea how I can solve this?
thanks
mark.
You need to configure ViewResolver.
Here is sample configuration:
<bean id="viewResolver"
class=" org.springframework.web.servlet.view. InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
When you do return new ModelAndView("hello", "message", message);
from above conf. it will try loading
prefix value + view name + suffix value
which will be required jsp.
Also you need to map your servlet in web.xml following way
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
I belive the problem is not the View resolver (it would print other exceptions).
Read the error message carfully, it tells what the problem is:
message /Spring3MVC/hello.html description
The requested resource (/Spring3MVC/hello.html) is not available.
It is that the hello .html (handler) can not be found, not the jsp. -- But I don't know what the exact problem it. -- I tryed to reproduce the error, but I did not get exact the same error message.
added -- find the problem
When you start the Server it prints all mappings to the controller in the log file. In your case there must by something like
INFO : org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapped URL path [/hallo] onto handler 'halloController'
If you don't have such a statement, then something is wrong with your context scan, or you have forget to enable the annotation driven MVC #Controller programming model. This can be enabled by adding:
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
I had the same issue.
Steps to Recreate
Open the Dashboard in Spring Tool Suite
Click "Spring Template
Project" in the "Create" area on the Dashboard
Right click on the newly created project in the Package Explorer pane of STS
SelectRun As > Run on Server
Choose Tomcat as your server and click Finish
Expected Result
The browser should launch and display the Hello World home page as defined by the HomeController > home action and the home.jsp view page.
Actual Result
404 Error
The Solution
1. Open up HomeController.java
2. Add a space anywhere in the file. Yeah. A space. Hit the spacebar. This is the solution. LOL
3. Run the project again as you did before.
This gives you the expected result.
My Hypothesis
The HomeController class isn't compiling initially, so the component-scan method isn't finding it; making it necessary to make a change to the file, and save it. This forces the class to be compiled, and therefore makes the home controller and the /home action discoverable.
I messed around with configuration files until I was pulling my hair out. I can't even tell you what made me think to try this. ;-) Glad I got it figured out though. Hopefully the Spring MVC 3 team will look into this, as it could easily create a serious barrier to entry to an otherwise cool framework.

Categories

Resources