Spring MVC Page is not rendering the success page using simpleformcontroller - spring

Iam wrote simple spring mvc apps.But I unable to redirect one page to another page. I mentioned code snippet below
Claims-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-2.5.xsd">
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props><prop key="/loginpage.htm">loginFormController</prop></props>
</property>
</bean>
<bean id="loginFormController" class="com.aims.controller.LoginFormController">
<property name="sessionForm"><value>true</value></property>
<property name="commandName"><value>LoginFormCommand</value></property>
<property name="commandClass"><value>com.aims.commands.LoginFormCommand</value></property>
<property name="validator"><ref bean="loginformValidator"/></property>
<property name="formView"><value>loginpage</value></property>
<property name="successView"><value>body</value></property>
</bean>
<bean id="loginformValidator" class="com.aims.validator.LoginFormValidator"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
<property name="suffix"><value>.jsp</value></property>
</bean>
</beans>
Controller:
public class LoginFormController extends SimpleFormController {
public ModelAndView onSubmit(Object command, BindException bindException) throws Exception {
System.out.println("LoginFormController:onSubmit============");
LoginFormCommand loginform = (LoginFormCommand) command;
System.out.println("username" + loginform.getUsername() + "Password"
+ loginform.getPassword());
return new ModelAndView(new RedirectView("/WEB-INF/view/jsp/"
+ getSuccessView()));
}}
I have two jsp one is
Webroot>loginpage.jsp
view->jsp>body.jsp
When the browser opens its automatically called loginpage.jsp(web.xml>welecome-file) and after success iam trying to call view->jsp>body.jsp.But it doesn't move to body.jsp.Please need help.

With a redirect view, you must specify the actual URL of the target, not a path to an internal jsp. Instead of rendering a jsp, Spring MVC will redirect the user to this URL.
Example: new ModelAndView(new RedirectView("/example/helloworld.html")).
Of course, the target has to exist.

Related

Spring MVC - No mapping found for HTTP request with URI [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 6 years ago.
I'm aware that there are loads of questions on the topic but none of the solutions i found here worked for me.
I'm using Spring with Jetty 6 so i don't have a web.xml file. The mapping for the spring dispatcher servlet is set to "/" in jetty's config
dispatcher:
<bean class="org.mortbay.jetty.servlet.ServletHolder">
<property name="name" value="spring" />
<property name="servlet">
<bean class="org.springframework.web.servlet.DispatcherServlet" />
</property>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:com/project/config/spring-servlet.xml" />
</map>
</property>
</bean>
... mapping:
<bean class="org.mortbay.jetty.servlet.ServletMapping">
<property name="servletName" value="spring"></property>
<property name="pathSpec" value="/"></property>
</bean>
The spring-servlet.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="..." ...>
<context:component-scan base-package="com.project.web" />
<mvc:annotation-driven />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
And i have a simple controller called HelloController:
#Controller
public class HelloController {
#RequestMapping(method = RequestMethod.GET, value="/welcome")
public String sayHello(ModelMap model){
model.addAttribute("message", "Spring 3 MVC Hello World");
return "hello";
}
}
Reading the logs it seem to work but i get the following error:
No mapping found for HTTP request with URI [/WEB-INF/pages/hello.jsp] in DispatcherServlet with name 'spring'
which i don't understand. it maps the "/welcome" to /WEB-INF/pages/hello.jsp but it still says page cannot be found, which is just there where it seems to look for it. I added the WEB-INF folder to the classpath but it's still the same. Do you have any idea why's that?
Are you sure the package name is correct in this?
<context:component-scan base-package="com.project.web" />
The request mapping path in the controller is relative to your http://your-domain/your-app/. If your app name is welcome use url http://localhost:25001/welcome/welcome or change the requestmapping to #RequestMapping(method = RequestMethod.GET, value="/") so you can use url http://localhost:25001/welcome
Is your hello.jsp directly under WEB-INF/pages?
Can you change the Dispatcher Servlet mapping to this and try
<property name="pathSpec" value="*.html"></property>

Mapping .jsp Spring

Today I'm working on a project in Java Spring, especially in CONTEXT-SERVLET.xml (context) where normally declare a bean to link a .jsp with a Java class or controller (mapping).
Traditional workflow is: a viewA.jsp is linked (mapping) to controller.java (controller) and this controller.java dispatches another viewB.jsp.
Can you link a viewA.jsp to another viewB.Jsp without going through a controller?
How do this in CONTEXT-SERVLET.xml?
You can use ParameterizableViewController to redirect a request to jsp file without visiting controller.
For example
1. Mapping /welcome.htm to welcomeController
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/welcome.htm">welcomeController</prop>
</props>
</property>
</bean>
2. Mapping viewName property of welcomeController to WelcomePage
<bean name="welcomeController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName" value="WelcomePage" />
</bean>
3. Defining view resolver
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
It will map /welcome.htm to /WEB-INF/pages/welcomePage.jsp.
Source for more details.
< mvc:view-controller path="/" view-name="home" />
This is a shortcut for defining a ParameterizableViewController that immediately forwards to a view when invoked. Use it in static cases when there is no Java controller logic to execute before the view generates the response.
see link http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-view-controller

Injection of the sessionFactory not working

I'm new with Spring and I want to inject the sessionFactory and its not working at all. I'm starting a web server Jetty and then I load the context. After i start a GWT web application, I make a call on the server side and I try to get some info but I get a null pointer. There is no error at all so it make it difficult to know where the problem is. I know its suppose to work because I saw it working on a project I worked on some times ago. Any help will be appreciate. (Sorry for my possibly bad english)
Here is the context.xml :
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:security="http://www.springframework.org/schema/security"
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/tx http://www.springframework.org/schema
/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema
/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema
/security/spring-security-3.0.xsd">
<!-- Standard spring initialization -->
<context:component-scan base-package="com.test">
</context:component-scan>
<tx:annotation-driven transaction-manager="txManager"/>
<!-- Connection to the database-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-
method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="123456789" />
</bean>
<!-- Hibernate session factory-->
<bean id="jpaSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.domain"/>
<property name="namingStrategy" >
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- Hibernate session factory -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="jpaSessionFactory" />
</bean>
</beans>
Here is the main :
public static void main(String[] args) {
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[]
{ new AppContextBuilder().buildWebAppContext()});
final JettyServer jettyServer = new JettyServer();
jettyServer.setHandler(contexts);
Runnable runner = new Runnable() {
#Override
public void run() {
new ServerRunner(jettyServer);
}
};
EventQueue.invokeLater(runner);
new ClassPathXmlApplicationContext("context.xml");
}
Here is the class Test where I want the injection :
#Component("test")
public class TEST{
#Resource(name="jpaSessionFactory")
private SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
public List<Personne> getPersonnes() {
Session s = sessionFactory.getCurrentSession();
Query query = s.createQuery("from Person");
return query.list();
}
}
Here is the server side from the application (not shown completely)
/*** The server side implementation of the RPC service.
*/
#SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
#Resource
private TEST t;
public String greetServer(String input) throws IllegalArgumentException {
// Verify that the input is valid.
if (!FieldVerifier.isValidName(input)) {
// If the input is not valid, throw an IllegalArgumentException
back to
// the client.
throw new IllegalArgumentException(
"Name must be at least 4 characters long");
}
t.getPersons(); // NULL pointer here
.........................
The MySQL tables are created like it should, so all the scanning seems to work.
Thanks
Bob
This is because the GreetingServiceImpl class is not created by spring - it is servlet that is initialized by the container directly. Follow the instructions in this article to fix the issue. I have copied the relevant code from the article.
#Override
public void init() throws ServletException {
super.init();
final WebApplicationContext ctx =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
if (ctx == null) {
throw new IllegalStateException("No Spring web application context found");
}
ctx.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
}

org.hibernate.HibernateException: No Session found for current thread

I'm getting the above exception with Spring3 and Hibernte4
The following is my bean xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<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:3306/GHS"/>
<property name="username" value="root"/>
<property name="password" value="newpwd"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.example.ghs.model.timetable</value>
</list>
</property>
</bean>
<bean id="baseDAO"
class="com.example.ghs.dao.BaseDAOImpl"/>
</beans>
My BaseDAO class looks like this
public class BaseDAOImpl implements BaseDAO{
private SessionFactory sessionFactory;
#Autowired
public BaseDAOImpl(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
#Override
public Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
}
The following code throws the exception in the title
public class Main {
public static void main(String[] args){
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("dao-beans.xml");
BaseDAO bd = (BaseDAO) context.getBean("baseDAO");
bd.getCurrentSession();
}
}
Does anyone have an idea about how to solve this problem?
getCurrentSession() only makes sense inside a scope of transaction.
You need to declare an appropriate transaction manager, demarcate boundaries of transaction and perform data access inside it. For example, as follows:
<bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name = "sessionFactory" ref = "sessionFactory" />
</bean>
.
PlatformTransactionManager ptm = context.getBean(PlatformTransactionManager.class);
TransactionTemplate tx = new TransactionTemplate(ptm);
tx.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
// Perform data access here
}
});
See also:
10. Transaction Management
13.3 Hibernate
I came across same problem and got solved as below
Added #Transactional on daoImpl class
Added trnsaction manager in configuration file:
<tx:annotation-driven/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
I'll just add something that took me some time to debug : don't forget that a #Transactional annotation will only work on "public" methods.
I put some #Transactional on "protected" ones and got this error.
Hope it helps :)
http://docs.spring.io/spring/docs/3.1.0.M2/spring-framework-reference/html/transaction.html
Method visibility and #Transactional
When using proxies, you should apply the #Transactional annotation
only to methods with public visibility. If you do annotate protected,
private or package-visible methods with the #Transactional annotation,
no error is raised, but the annotated method does not exhibit the
configured transactional settings. Consider the use of AspectJ (see
below) if you need to annotate non-public methods.
Which package u have put the BaseDAOImpl class in.. I think It requires a package name similar to the one u have used in the application context xml and it requires a relevant annotation too.

MessageSource and PropertyPlaceholderConfigurer cannot load messages but with classpath*

My applicationContext.xml is in path:
src/main/resources/META-INF/spring
and property files are in path:
src/main/resources/messages
and I load spring context in web.xml as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/applicationContext.xml</param-value>
</context-param>
when I am configuring MessageSource and PropertyPlaceholderConfigurer as follows:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:messages/apps.properties</value>
</list>
</property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages/ValidationMessages</value>
<value>classpath:messages/app</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
they both don't work, it only works when I change classpath to classpath*
Any ideas why?
From Spring documentation:
4.7.2.2 The classpath*: prefix
[...] location string may use the special classpath*: prefix: [...]
This special prefix specifies that all classpath resources that match the given name must be obtained [...], and then merged to form the final application context definition.
Are you sure there are no other messages/apps.properties files on your CLASSPATH coincidentally taking precedence and overriding your file? This description suggests that you might have several same named files that are merged when * is used.
Can you check this by calling:
SomeClass.class.getClassLoader().getResources("/messages/apps.properties");
?
Look at this excellent article for classpath v classpth* difference in regards to spring resource loading, I did some testing on your problem in my testing it worked whether i used classpath or classpath*
I am listing the code here about the test i did
I created a this directory structure (META-INF/spring under src/main/resource) placed context.xml
I am listing complete context.xml here
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:messages/apps.properties</value>
</list>
</property>
</bean>
<bean class="prasanna.service.TestBean">
<property name="appName" value="${appname}"></property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages/ValidationMessages</value>
<value>classpath:messages/apps</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
</beans>
Listing for apps.properties
appname=spring mvc app
Listing for ValidationMessages.properties
error.name=Invalid name
TestBean is rather simple
public class TestBean
{
private String appName;
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
}
I am using a simple java class to load the property files and read them
public class LoadContext
{
public static void main(String[] args)
{
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:META-INF/spring/context.xml"});
ReloadableResourceBundleMessageSource msgs = ctx.getBean(ReloadableResourceBundleMessageSource.class);
TestBean testBean = ctx.getBean(TestBean.class);
Assert.assertTrue(testBean.getAppName().equals("spring mvc app"));
String msg = msgs.getMessage("appname", new Object[]{new DefaultMessageSourceResolvable("appname")}, null);
System.out.println(" "+ msg);
String msg2 = msgs.getMessage("error.name", new Object[]{new DefaultMessageSourceResolvable("error.name")}, null);
System.out.println(" "+ msg2);
}
}

Resources