Can you please help me figure out how to invoke the login page by using my controller?
Here is my code:
package com.mvc.demo;
public class Emp {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
MvcDemo.java (it's my controller; just for invoking login page)
package com.mvc.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
public class MvcDemo {
#RequestMapping(value="/login", method = RequestMethod.GET)
public String showForm(Emp em) {
return "login";
}
}
dispatcher-servlet.xml
<context:component-scan base-package="com.mvc.demo" />
<mvc:annotation-driven />
<beans>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
web.xml
<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>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
login.jsp
<form:form action="#" method = "post" modelAttribute="emp">
<form:label path="username">Enter your user-name</form:label>
<form:input id="username" name="username" path="name" /><br>
<form:label path="username">Please enter your password</form:label>
<form:password id="password" name="password" path="password" /><br>
<input type="submit" value="Submit" />
</form:form>
project Structure:
MvcDemo
JavaResources
src
com.mvc.demo
WebContent
jsp
login.jsp
WEB-INF
lib
web.xml
dispatcher-servlet.xml
index.jsp
You are missing #Controller annotation on your controller class. Spring does not create a handler for url unless you instantiate a controller by using annotation.
It does the same as in your code,when you hit url with localhost:8080/Mvc_Demo/login it must show your login.jsp,
hope this solves your problem.
package com.mvc.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
public class MvcDemo {
#RequestMapping(value="/login", method = RequestMethod.GET)
public String showForm( )
{
ModelAndView mv = new ModelAndView("login");
return mv;
}
}
Try this code:
package com.mvc.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class MvcDemo {
// To call the view for login
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login() {
return new ModelAndView("login","newEmp", new Emp());
}
// To call the validate login after submit
#RequestMapping(value = "/user-login", method = RequestMethod.POST)
#ResponseBody
public ModelAndView userLogin(Emp emp) {
//TODO check 'emp' object to validate user
return new ModelAndView("home");
}
}
Related
I am completely new to Spring (MVC) and Hibernate and I am trying to learn it.
I made up the following authentication scenario to practice but I am not having much luck getting it to work.
Scenario:
I have an HTML form (homepageForm.jsp) that sends username and password to HomeController.
The HomeController gets the form parameters (username/password) and compares the form params to username & password retrieved from a database.
If there's a match, the user will be presented with the dashboard.jsp. If there's a mismatch, the error.jsp will be loaded instead.
The information from the db is retrieved by the "UserRetrievalService".
I am getting the following error:
:::: ERROR
type Exception report
message Request processing failed; nested exception is java.lang.NullPointerException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NullPointerException
com.springdemo.mvc.HomeController.processLoginForm(HomeController.java:91)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
I suspect it's related to the way the servlet.xml is referenced.
The line 91 in the HomeController is this one:
User user = userRetrievalService.getUser();
or perhaps I am using the #Autowired incorrectly.
Could anyone please give me some tips how to resolve this?
Thank you!
Here's some additional info about the project.
**** 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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.springdemo.mvc" />
<context:component-scan base-package="com.springdemo.model" />
<mvc:annotation-driven/>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
**** web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>spring-mvc-demo</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
**** homepageForm.jsp
<html>
<head>
<title>Homepage Form</title>
</head>
<body>
<form action="processLogin" method="POST">
<div>
<label>Username</label> <input type="text" name="username" placeholder="username" />
</div>
<div>
<label>Password</label> <input type="text" name="password" placeholder="password" />
</div>
<input type="submit" value="Login" />
</form>
</body>
</html>
**** User.java
package com.springdemo.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "user")
public class User implements AbstractUser {
#Id
#Column(name = "id")
private int id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "first_name")
private String firstname;
#Column(name = "last_name")
private String lastname;
#Column(name = "email")
private String email;
public User() {
}
public User(int id, String username, String password, String firstname, String lastname, String email) {
super();
this.id = id;
this.username = username;
this.password = password;
this.firstname = firstname;
this.lastname = lastname;
this.email = email;
}
+ getters & setters
}
**** UserService
public interface UserService {
public User getUser();
}
**** UserRetrievalService
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.stereotype.Component;
#Component
public class UserRetrievalService implements UserService {
#Override
public User getUser() {
System.out.println("UserRetrievalService called...");
Configuration config = new Configuration().configure("hibernate.cfg.xml");
config.addAnnotatedClass(User.class);
SessionFactory sessionFactory = config.buildSessionFactory();
// create a session
Session session = sessionFactory.getCurrentSession();
try {
// start trans
session.beginTransaction();
// get & create user
User user = session.get(User.class, 1);
// commit trans
session.getTransaction().commit();
System.out.println("UserRetrievalService : commit successful...");
System.out.println(" >>>> USER: " + user.getId() + " " + user.getUsername() + " " + user.getPassword() + " " + user.getFirstname() + " " + user.getLastname());
return user;
} finally {
sessionFactory.close();
}
}
}
**** HomeController.java
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.springdemo.model.User;
import com.springdemo.model.UserRetrievalService;
#Controller
public class HomeController {
...
private UserRetrievalService userRetrievalService;
#Autowired
public UserRetrievalService getUserRetrievalService() {
return userRetrievalService;
}
#RequestMapping("/processLogin")
public ModelAndView processLoginForm(HttpServletRequest request) {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username : " + username);
System.out.println("password : " + password);
User user = userRetrievalService.getUser();
ModelAndView modelAndView;
if (username.equalsIgnoreCase(user.getUsername()) && (password.equalsIgnoreCase(user.getPassword()))) {
modelAndView = new ModelAndView("dashboard"); // page to be returned
} else {
modelAndView = new ModelAndView("error"); // page to be returned
}
// System.out.println("success: user id = " + user.getId());
modelAndView.addObject("myUser", user);
return modelAndView;
}
...
}
::::: hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/springtestdb?useSSL=false</property>
<property name="connection.username">*****</property>
<property name="connection.password">*****</property>
<!-- JDBC connection pool settings ... using built-in test pool -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">true</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
</session-factory>
</hibernate-configuration>
Your UserRetrievalService not properly injected.
You can use #Autowired or Constructor/Setter injection. In your case you used setter injection but not in a proper way
It should be like
private UserRetrievalService userRetrievalService;
#Autowired
public UserRetrievalService setUserRetrievalService(UserRetrievalService userRetrievalService) {
this.userRetrievalService = userRetrievalService;
}
Suggestion regarding hibernate configuraion.
You need keep hibernate.cfg.xml under classpath
As yours is maven project, the ideal place would be /src/main/resources/
Please refer to https://stackoverflow.com/a/29352557/7063373 for more clarity.
According to the Javadoc for Autowired, the annotation can be used on "a constructor, field, setter method or config method". In HomeController put Autowired annotation in service field.
#Autowired
private UserRetrievalService userRetrievalService;
I am trying spring security authentication using database facing issues
DataController.java
package com.anzy.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.anzy.dao.DataDao;
import com.anzy.domain.Employee;
#Controller
public class DataController {
#Autowired
DataDao dataDao;
#RequestMapping("form")
public ModelAndView getForm(#ModelAttribute Employee employee) {
return new ModelAndView("form");
}
#RequestMapping("register")
public ModelAndView registerUser(#ModelAttribute Employee employee) {
dataDao.insertRow(employee);
return new ModelAndView("redirect:list");
}
#RequestMapping("list")
public ModelAndView getList()
{
List employeeList = dataDao.getList();
return new ModelAndView("list", "employeeList", employeeList);
}
#RequestMapping("delete")
public ModelAndView deleteUser(#RequestParam int id) {
dataDao.deleteRow(id);
return new ModelAndView("redirect:list");
}
#RequestMapping("edit")
public ModelAndView editUser(#RequestParam int id,
#ModelAttribute Employee employee) {
Employee employeeObject = dataDao.getRowById(id);
return new ModelAndView("edit", "employeeObject", employeeObject);
}
#RequestMapping("update")
public ModelAndView updateUser(#ModelAttribute Employee employee) {
dataDao.updateRow(employee);
return new ModelAndView("redirect:list");
}
}
User.java
package com.anzy.domain;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
#Entity
public class User implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name="username")
private String username;
#Column(name="password")
private String password;
#ManyToMany
#JoinTable(name="UserAndRoles",joinColumns=#JoinColumn(name="user_id"),inverseJoinColumns=#JoinColumn(name="role_id"))
private List<Role> roles;
#Enumerated(EnumType.STRING)
private UserStatus status;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public UserStatus getStatus() {
return status;
}
public void setStatus(UserStatus status) {
this.status = status;
}
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
Role.java
package com.anzy.domain;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
public class Role
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name="roleName")
private String roleName;
#ManyToMany(mappedBy="roles")
private List<User>users;
public Role(int id, String roleName, List<User> users)
{
super();
this.id = id;
this.roleName = roleName;
this.users = users;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
UserStatus.java
package com.anzy.domain;
public enum UserStatus
{
ACTIVE,
INACTIVE;
}
Employee.java
package com.anzy.domain;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="employetest")
public class Employee {
#Id
#GeneratedValue
private int id;
#Column(name = "firstname")
private String firstName;
#Column(name = "lastname")
private String lastName;
#Column(name = "email")
private String email;
#Column(name = "phone")
private String phone;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
UserDao.java
package com.anzy.dao;
import java.util.List;
import com.anzy.domain.User;
public interface UserDao
{
void addUser(User user);
void editUser(User user);
void deleteUser(int userId);
User findUser(int useId);
User findUserByName(String username);
List<User> getAllUser();
}
UserDaoImpl.java
package com.anzy.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.anzy.domain.User;
#Repository
public class UserDaoImpl implements UserDao
{
#Autowired
private SessionFactory session;
public void addUser(User user)
{
session.getCurrentSession().save(user);
}
public void editUser(User user) {
session.getCurrentSession().update(user);
}
public void deleteUser(int userId) {
session.getCurrentSession().delete(findUser(userId));
}
public User findUser(int userId) {
return (User) session.getCurrentSession().get(User.class,userId);
}
public User findUserByName(String username) {
Criteria criteria=session.getCurrentSession().createCriteria(User.class);
criteria.add(Restrictions.eq("username", username));
return (User)criteria.uniqueResult();
}
public List<User> getAllUser() {
// TODO Auto-generated method stub
return session.getCurrentSession().createQuery("from User").list();
}
}
UserDetailsServiceImpl.java
package com.anzy.services;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.anzy.dao.UserDao;
import com.anzy.domain.Role;
import com.anzy.domain.User;
import com.anzy.domain.UserStatus;
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService
{
#Autowired
private UserDao userDao;
#Transactional(readOnly=true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user=userDao.findUserByName(username);
if(user!=null)
{
String password=user.getPassword();
boolean enabled=user.getStatus().equals(UserStatus.ACTIVE);
boolean accountNonExpired=user.getStatus().equals(UserStatus.ACTIVE);
boolean credentialsNonExpired=user.getStatus().equals(UserStatus.ACTIVE);
boolean accountNonLocked=user.getStatus().equals(UserStatus.ACTIVE);
Collection <GrantedAuthority> authorities=new ArrayList<GrantedAuthority>();
for(Role role:user.getRoles())
{
authorities.add(new SimpleGrantedAuthority(role.getRoleName()));
}
org.springframework.security.core.userdetails.User secureUser=new org.springframework.security.core.userdetails.User(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
return secureUser;
}
else
{
throw new UsernameNotFoundException("User not found !!!");
}
}
}
DataDao.java
package com.anzy.dao;
import java.util.List;
import com.anzy.domain.Employee;
public interface DataDao
{
public int insertRow(Employee employee);
public List<Employee> getList();
public Employee getRowById(int id);
public int updateRow(Employee employee);
public int deleteRow(int id);
}
DataDaoImpl.java
package com.anzy.dao;
import java.io.Serializable;
import java.util.List;
import javax.transaction.Transactional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import com.anzy.domain.Employee;
public class DataDaoImpl implements DataDao {
#Autowired
SessionFactory sessionFactory;
#Transactional
public int insertRow(Employee employee) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.saveOrUpdate(employee);
tx.commit();
Serializable id = session.getIdentifier(employee);
session.close();
return (Integer) id;
}
public List getList() {
Session session = sessionFactory.openSession();
#SuppressWarnings("unchecked")
List employeeList = session.createQuery("from Employee")
.list();
session.close();
return employeeList;
}
public Employee getRowById(int id) {
Session session = sessionFactory.openSession();
Employee employee = (Employee) session.load(Employee.class, id);
System.out.println(employee);
return employee;
}
public int updateRow(Employee employee) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.saveOrUpdate(employee);
tx.commit();
Serializable id = session.getIdentifier(employee);
session.close();
return (Integer) id;
}
public int deleteRow(int id) {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Employee employee = (Employee) session.load(Employee.class, id);
session.delete(employee);
tx.commit();
Serializable ids = session.getIdentifier(employee);
session.close();
return (Integer) ids;
}
}
spring-config.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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.anzy" />
<context:property-placeholder location="classpath:database.properties" />
<mvc:annotation-driven />
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
<property name="initialSize" value="20" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.anzy.domain.Employee</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<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>
<bean id="dataDaoImpl" class="com.anzy.dao.DataDaoImpl" />
<!-- <bean id="dataServiceImpl" class="com.beingjavaguys.services.DataServiceImpl" />
-->
</beans>
spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="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-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<http auto-config="true">
<intercept-url pattern="/*" access="isAuthenticated()"/>
<form-login />
<!-- <logout invalidate-session="true" />
--> </http>
<!-- <authentication-manager>
<authentication-provider>
<user-service>
<user name="joseph" password="bagnes" authorities="Admin,User" />
<user name="bernabe" password="jose" authorities="User" />
</user-service>
</authentication-provider>
</authentication-manager> -->
<beans:bean id="daoAuthenticationProvider" class=" org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<beans:property name="userDetailsService" ref="userDetailsService"></beans:property>
</beans:bean>
<beans:bean id="authenticationManager" class="org.springframework.security.authentication.AuthenticationProvider">
<beans:property name="providers">
<beans:list>
<beans:ref local="daoAuthenticationProvider"/>
</beans:list>
</beans:property>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService">
<password-encoder hash="md5"></password-encoder>
</authentication-provider>
</authentication-manager>
</beans:beans>
web.xml
<web-app 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"
version="2.5">
<display-name>Sample Spring Maven Project</display-name>
<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/spring-config.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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
</web-app>
(edited from a previous version)
I created a simplified setting for your problem, and got the code to work.
Here are the two Java classes, first the service (in essense a stub, I did not try to simplify it further, the code has no particular significance):
package com.anzy.services;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService
{
#Transactional(readOnly=true)
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
Collection <GrantedAuthority> authorities=new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
org.springframework.security.core.userdetails.User secureUser=new org.springframework.security.core.userdetails.User("user", "user", true, true, true, true, authorities);
return secureUser;
}
}
and here is the controller (again, simplified to have just one method)
package com.anzy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class DataController {
#RequestMapping("form")
public ModelAndView getForm() {
return new ModelAndView("form");
}
}
the four files under WEB-INF are:
spring-config.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" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.anzy">
<context:exclude-filter type="regex" expression="com.anzy.controller.*"/>
</context:component-scan>
<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>
spring-mvc.xml
<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.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.anzy.controller"/>
</beans>
spring-security.xml (note that I added use-expressions="true" to the element <http..)
<?xml version="1.0" encoding="UTF-8"?>
<bean:beans xmlns:bean="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/*" access="isAuthenticated()"/>
<form-login />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService"/>
</authentication-manager>
</bean:beans>
web.xml
<web-app 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"
version="2.5">
<display-name>Sample Spring Maven Project</display-name>
<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/spring-mvc.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>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/spring-config.xml
</param-value>
</context-param>
<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>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
</web-app>
The resulting web application starts with no exceptions.
If, however, I change in web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/spring-config.xml
</param-value>
</context-param>
to
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
and
<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/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
to
<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/spring-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
then I get precisely the exception which was the subject of your question
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDetailsService' is defined
Below is my code, and always get null for query method, i do not know why this happen. I can get the form param by other ways, such as #RequestParam etc. Do i need to set configuration for the Phone Class in the XML file? if so, how can i configure Phone Class in XML? My XML is recharge-servlet.xml.
Below is the Controller:
package com.nu.template.recharge;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
#RequestMapping("/mobile")
public class XJMobile {
#RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView getIndexPage() {
ModelAndView mav = new ModelAndView("recharge");
return mav;
}
#RequestMapping(value = "/query", method = RequestMethod.POST)
public String query(Phone phone) {
System.out.println(phone.getNumber());
return "helloworld";
}
}
Form:
<form action="query" method="POST" name="phone_form">
<section>
<label>phone:</label>
<input type="text" name="phone_number" />
</section>
<input type="submit" value="submit">
</form>
Phone Class:
package com.nu.template.recharge;
public class Phone {
private String phone_number;
public String getNumber() {
return this.phone_number;
}
public void setNumber(String phone_number) {
this.phone_number = phone_number;
}
}
recharge-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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.nu.template.recharge"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>
<property name="suffix" value=".jsp"/>
</bean>
You can get your Phone object initialized by
#RequestMapping(value = "query", method = RequestMethod.POST)
public String query(#RequestParam("phone_number") Phone phone) {
System.out.println(phone.getNumber());
return "helloworld";
}
Spring generally looks for same parameter type for binding or you can tell it to bind with your pojo, given a setter method which accepts parameter type.
I'm quite new to spring boot and I'd like to create a multiple datasource for my project.
Here is my current case. I have two packages for entity for multiple database. Let's say
com.test.entity.db.mysql ; for entities that belong to MySql
com.test.entity.db.h2 ; for entities that belong to H2 Databases
So, currently I have two entities class
UserMySql.java
#Entity
#Table(name="usermysql")
public class UserMysql{
#Id
#GeneratedValue
public int id;
public String name;
}
UserH2.java
#Entity
#Table(name="userh2")
public class Userh2 {
#Id
#GeneratedValue
public int id;
public String name;
}
I'd like to achieve a configuration where if I create user from UserMySql, it will be saved to MySql Database, and if I create user from Userh2 it will be saved to H2 Databases. So, I also have two DBConfig, let's say MySqlDbConfig and H2DbConfig.
(com.test.model is package where I'll put my Repositories class. It will be defined below)
MySqlDbConfig.java
#Configuration
#EnableJpaRepositories(
basePackages="com.test.model",
entityManagerFactoryRef = "mysqlEntityManager")
public class MySqlDBConfig {
#Bean
#Primary
#ConfigurationProperties(prefix="datasource.test.mysql")
public DataSource mysqlDataSource(){
return DataSourceBuilder
.create()
.build();
}
#Bean(name="mysqlEntityManager")
public LocalContainerEntityManagerFactoryBean mySqlEntityManagerFactory(
EntityManagerFactoryBuilder builder){
return builder.dataSource(mysqlDataSource())
.packages("com.test.entity.db.mysql")
.build();
}
}
H2DbConfig.java
#Configuration
#EnableJpaRepositories(
entityManagerFactoryRef = "h2EntityManager")
public class H2DbConfig {
#Bean
#ConfigurationProperties(prefix="datasource.test.h2")
public DataSource h2DataSource(){
return DataSourceBuilder
.create()
.driverClassName("org.h2.Driver")
.build();
}
#Bean(name="h2EntityManager")
public LocalContainerEntityManagerFactoryBean h2EntityManagerFactory(
EntityManagerFactoryBuilder builder){
return builder.dataSource(h2DataSource())
.packages("com.test.entity.db.h2")
.build();
}
}
My application.properties file
#DataSource settings for mysql
datasource.test.mysql.jdbcUrl = jdbc:mysql://127.0.0.1:3306/test
datasource.test.mysql.username = root
datasource.test.mysql.password = root
datasource.test.mysql.driverClassName = com.mysql.jdbc.Driver
#DataSource settings for H2
datasource.test.h2.jdbcUrl = jdbc:h2:~/test
datasource.test.h2.username = sa
# DataSource settings: set here configurations for the database connection
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.validation-query=SELECT 1
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.hibernate.show_sql = true
spring.jpa.hibernate.format_sql = true
server.port=8080
endpoints.shutdown.enabled=false
And then for crud I have UserMySqlDao and UserH2Dao
UserMySqlDao.java
#Transactional
#Repository
public interface UserMysqlDao extends CrudRepository<UserMysql, Integer>{
public UserMysql findByName(String name);
}
UserH2Dao.java
#Transactional
#Repositories
public interface UserH2Dao extends CrudRepository<Userh2, Integer>{
public Userh2 findByName(String name);
}
And for last, I have an UserController as endpoint to access my service
UserController.java
#Controller
#RequestMapping("/user")
public class UserController {
#Autowired
private UserMysqlDao userMysqlDao;
#Autowired
private UserH2Dao userH2Dao;
#RequestMapping("/createM")
#ResponseBody
public String createUserMySql(String name){
UserMysql user = new UserMysql();
try{
user.name = name;
userMysqlDao.save(user);
return "Success creating user with Id: "+user.id;
}catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
}
#RequestMapping("/createH")
#ResponseBody
public String createUserH2(String name){
Userh2 user = new Userh2();
try{
user.name = name;
userH2Dao.save(user);
return "Success creating user with Id: "+user.id;
}catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
}
}
Application.java
#Configuration
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
#EntityScan(basePackages="com.test.entity.db")
#ComponentScan
public class Application {
public static void main(String[] args) {
System.out.println("Entering spring boot");
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.print(beanName);
System.out.print(" ");
}
System.out.println("");
}
}
With this configuration my Spring boot run well, but when I access
http://localhost/user/createM?name=myname it writes an exception
Error creating the user: org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
I've googling around and haven't got a solution yet. Any ideas why this exception occurs? And is this the best way to implement multiple datasource to implement my case above? I'm open to full refactor if needed.
Thanks
I think you can find it usefull
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources
It shows how to define multiple datasources & assign one of them as primary.
Here is a rather full example, also contains distributes transactions - if you need it.
http://fabiomaffioletti.me/blog/2014/04/15/distributed-transactions-multiple-databases-spring-boot-spring-data-jpa-atomikos/
What you need is to create 2 configuration classes, separate the model/repository packages etc to make the config easy.
Also, in above example, it creates the data sources manually. You can avoid this using the method on spring doc, with #ConfigurationProperties annotation. Here is an example of this:
http://xantorohara.blogspot.com.tr/2013/11/spring-boot-jdbc-with-multiple.html
Hope these helps.
I faced same issue few days back, I followed the link mentioned below and I could able to overcome the problem
http://www.baeldung.com/spring-data-jpa-multiple-databases
I solved the problem (How to connect multiple database using spring and Hibernate) in this way, I hope it will help :)
NOTE: I have added the relevant code, kindly make the dao with the help of impl I used in the below mentioned code.
web.xml
<?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_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>MultipleDatabaseConnectivityInSpring</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/dispatcher-servlet.xml
</param-value>
</context-param>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="localPersistenceUnitOne"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>in.india.entities.CustomerDetails</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.jdbc.batch_size" value="0" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankar?sslmode=require" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
<persistence-unit name="localPersistenceUnitTwo"
transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>in.india.entities.CompanyDetails</class>
<exclude-unlisted-classes />
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.jdbc.batch_size" value="0" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/shankarTwo?sslmode=require" />
<property name="hibernate.connection.username" value="username" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
dispatcher-servlet
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task" xmlns:p="http://www.springframework.org/schema/p"
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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
default-autowire="byName"
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-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/task http://www.springframework.org/schema/task/spring-task-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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Configure messageSource -->
<mvc:annotation-driven />
<context:component-scan base-package="in.india.*" />
<bean id="messageResource"
class="org.springframework.context.support.ResourceBundleMessageSource"
autowire="byName">
<property name="basename" value="messageResource"></property>
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="entityManagerFactoryOne"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
autowire="constructor">
<property name="persistenceUnitName" value="localPersistenceUnitOne" />
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
autowire="byName">
<property name="basename" value="messageResource" />
</bean>
<bean id="entityManagerFactoryTwo"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
autowire="constructor">
<property name="persistenceUnitName" value="localPersistenceUnitTwo" />
</bean>
<bean id="manager1" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryOne" />
</bean>
<bean id="manager2" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryTwo" />
</bean>
<tx:annotation-driven transaction-manager="manager1" />
<tx:annotation-driven transaction-manager="manager2" />
<!-- declare dependies here -->
<bean class="in.india.service.dao.impl.CustomerServiceImpl" />
<bean class="in.india.service.dao.impl.CompanyServiceImpl" />
<!-- Configure MVC annotations -->
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</beans>
java class to persist into one database
package in.india.service.dao.impl;
import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.transaction.annotation.Transactional;
public class CompanyServiceImpl implements CompanyService {
#PersistenceContext(unitName = "entityManagerFactoryTwo")
EntityManager entityManager;
#Transactional("manager2")
#Override
public boolean companyService(CompanyDetails companyDetails) {
boolean flag = false;
try
{
entityManager.persist(companyDetails);
flag = true;
}
catch (Exception e)
{
flag = false;
}
return flag;
}
}
java class to persist in another database
package in.india.service.dao.impl;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.transaction.annotation.Transactional;
import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;
public class CustomerServiceImpl implements CustomerService {
#PersistenceContext(unitName = "localPersistenceUnitOne")
EntityManager entityManager;
#Override
#Transactional(value = "manager1")
public boolean customerService(CustomerDetails companyData) {
boolean flag = false;
entityManager.persist(companyData);
return flag;
}
}
customer.jsp
<%#page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<center>
<h1>SpringWithMultipleDatabase's</h1>
</center>
<form:form method="GET" action="addCustomer.htm" modelAttribute="customerBean" >
<table>
<tr>
<td><form:label path="firstName">First Name</form:label></td>
<td><form:input path="firstName" /></td>
</tr>
<tr>
<td><form:label path="lastName">Last Name</form:label></td>
<td><form:input path="lastName" /></td>
</tr>
<tr>
<td><form:label path="emailId">Email Id</form:label></td>
<td><form:input path="emailId" /></td>
</tr>
<tr>
<td><form:label path="profession">Profession</form:label></td>
<td><form:input path="profession" /></td>
</tr>
<tr>
<td><form:label path="address">Address</form:label></td>
<td><form:input path="address" /></td>
</tr>
<tr>
<td><form:label path="age">Age</form:label></td>
<td><form:input path="age" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form:form>
</body>
</html>
company.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
<center><h1>SpringWithMultipleDatabase's</h1></center>
<form:form method="GET" action="addCompany.htm" modelAttribute="companyBean" >
<table>
<tr>
<td><form:label path="companyName">Company Name</form:label></td>
<td><form:input path="companyName" /></td>
</tr>
<tr>
<td><form:label path="companyStrength">Company Strength</form:label></td>
<td><form:input path="companyStrength" /></td>
</tr>
<tr>
<td><form:label path="companyLocation">Company Location</form:label></td>
<td><form:input path="companyLocation" /></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Home</title>
</head>
<body>
<center><h1>Multiple Database Connectivity In Spring sdfsdsd</h1></center>
<a href='customerRequest.htm'>Click here to go on Customer page</a>
<br>
<a href='companyRequest.htm'>Click here to go on Company page</a>
</body>
</html>
success.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>ScheduleJobs</title>
</head>
<body>
<center><h1>SpringWithMultipleDatabase</h1></center>
<b>Successfully Saved</b>
</body>
</html>
CompanyController
package in.india.controller;
import in.india.bean.CompanyBean;
import in.india.entities.CompanyDetails;
import in.india.service.CompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class CompanyController {
#Autowired
CompanyService companyService;
#RequestMapping(value = "/companyRequest.htm", method = RequestMethod.GET)
public ModelAndView addStudent(ModelMap model) {
CompanyBean companyBean = new CompanyBean();
model.addAttribute(companyBean);
return new ModelAndView("company");
}
#RequestMapping(value = "/addCompany.htm", method = RequestMethod.GET)
public ModelAndView companyController(#ModelAttribute("companyBean") CompanyBean companyBean, Model model) {
CompanyDetails companyDetails = new CompanyDetails();
companyDetails.setCompanyLocation(companyBean.getCompanyLocation());
companyDetails.setCompanyName(companyBean.getCompanyName());
companyDetails.setCompanyStrength(companyBean.getCompanyStrength());
companyService.companyService(companyDetails);
return new ModelAndView("success");
}
}
CustomerController
package in.india.controller;
import in.india.bean.CustomerBean;
import in.india.entities.CustomerDetails;
import in.india.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class CustomerController {
#Autowired
CustomerService customerService;
#RequestMapping(value = "/customerRequest.htm", method = RequestMethod.GET)
public ModelAndView addStudent(ModelMap model) {
CustomerBean customerBean = new CustomerBean();
model.addAttribute(customerBean);
return new ModelAndView("customer");
}
#RequestMapping(value = "/addCustomer.htm", method = RequestMethod.GET)
public ModelAndView customerController(#ModelAttribute("customerBean") CustomerBean customer, Model model) {
CustomerDetails customerDetails = new CustomerDetails();
customerDetails.setAddress(customer.getAddress());
customerDetails.setAge(customer.getAge());
customerDetails.setEmailId(customer.getEmailId());
customerDetails.setFirstName(customer.getFirstName());
customerDetails.setLastName(customer.getLastName());
customerDetails.setProfession(customer.getProfession());
customerService.customerService(customerDetails);
return new ModelAndView("success");
}
}
CompanyDetails Entity
package in.india.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "company_details")
public class CompanyDetails {
#Id
#SequenceGenerator(name = "company_details_seq", sequenceName = "company_details_seq", initialValue = 1, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "company_details_seq")
#Column(name = "company_details_id")
private Long companyDetailsId;
#Column(name = "company_name")
private String companyName;
#Column(name = "company_strength")
private Long companyStrength;
#Column(name = "company_location")
private String companyLocation;
public Long getCompanyDetailsId() {
return companyDetailsId;
}
public void setCompanyDetailsId(Long companyDetailsId) {
this.companyDetailsId = companyDetailsId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public Long getCompanyStrength() {
return companyStrength;
}
public void setCompanyStrength(Long companyStrength) {
this.companyStrength = companyStrength;
}
public String getCompanyLocation() {
return companyLocation;
}
public void setCompanyLocation(String companyLocation) {
this.companyLocation = companyLocation;
}
}
CustomerDetails Entity
package in.india.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "customer_details")
public class CustomerDetails {
#Id
#SequenceGenerator(name = "customer_details_seq", sequenceName = "customer_details_seq", initialValue = 1, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customer_details_seq")
#Column(name = "customer_details_id")
private Long customerDetailsId;
#Column(name = "first_name ")
private String firstName;
#Column(name = "last_name ")
private String lastName;
#Column(name = "email_id")
private String emailId;
#Column(name = "profession")
private String profession;
#Column(name = "address")
private String address;
#Column(name = "age")
private int age;
public Long getCustomerDetailsId() {
return customerDetailsId;
}
public void setCustomerDetailsId(Long customerDetailsId) {
this.customerDetailsId = customerDetailsId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Update 2018-01-07 with Spring Boot 1.5.8.RELEASE
If you want to know how to config it, how to use it, and how to control transaction. I may have answers for you.
You can see the runnable example and some explanation in https://www.surasint.com/spring-boot-with-multiple-databases-example/
I copied some code here.
First you have to set application.properties like this
#Database
database1.datasource.url=jdbc:mysql://localhost/testdb
database1.datasource.username=root
database1.datasource.password=root
database1.datasource.driver-class-name=com.mysql.jdbc.Driver
database2.datasource.url=jdbc:mysql://localhost/testdb2
database2.datasource.username=root
database2.datasource.password=root
database2.datasource.driver-class-name=com.mysql.jdbc.Driver
Then define them as providers (#Bean) like this:
#Bean(name = "datasource1")
#ConfigurationProperties("database1.datasource")
#Primary
public DataSource dataSource(){
return DataSourceBuilder.create().build();
}
#Bean(name = "datasource2")
#ConfigurationProperties("database2.datasource")
public DataSource dataSource2(){
return DataSourceBuilder.create().build();
}
Note that I have #Bean(name="datasource1") and #Bean(name="datasource2"), then you can use it when we need datasource as #Qualifier("datasource1") and #Qualifier("datasource2") , for example
#Qualifier("datasource1")
#Autowired
private DataSource dataSource;
If you do care about transaction, you have to define DataSourceTransactionManager for both of them, like this:
#Bean(name="tm1")
#Autowired
#Primary
DataSourceTransactionManager tm1(#Qualifier ("datasource1") DataSource datasource) {
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
return txm;
}
#Bean(name="tm2")
#Autowired
DataSourceTransactionManager tm2(#Qualifier ("datasource2") DataSource datasource) {
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource);
return txm;
}
Then you can use it like
#Transactional //this will use the first datasource because it is #primary
or
#Transactional("tm2")
This should be enough. See example and detail in the link above.
Use multiple datasource or realizing the separation of reading & writing.
you must have a knowledge of Class AbstractRoutingDataSource which support dynamic datasource choose.
Here is my datasource.yaml and I figure out how to resolve this case. You can refer to this project spring-boot + quartz. Hope this will help you.
dbServer:
default: localhost:3306
read: localhost:3306
write: localhost:3306
datasource:
default:
type: com.zaxxer.hikari.HikariDataSource
pool-name: default
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.default}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false
read:
type: com.zaxxer.hikari.HikariDataSource
pool-name: read
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.read}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false
write:
type: com.zaxxer.hikari.HikariDataSource
pool-name: write
continue-on-error: false
jdbc-url: jdbc:mysql://${dbServer.write}/schedule_job?useSSL=true&verifyServerCertificate=false&useUnicode=true&characterEncoding=utf8
username: root
password: lh1234
connection-timeout: 30000
connection-test-query: SELECT 1
maximum-pool-size: 5
minimum-idle: 2
idle-timeout: 600000
destroy-method: shutdown
auto-commit: false
Using two datasources you need their own transaction managers.
#Configuration
public class MySqlDBConfig {
#Bean
#Primary
#ConfigurationProperties(prefix="datasource.test.mysql")
public DataSource mysqlDataSource(){
return DataSourceBuilder
.create()
.build();
}
#Bean("mysqlTx")
public DataSourceTransactionManager mysqlTx() {
return new DataSourceTransactionManager(mysqlDataSource());
}
// same for another DS
}
And then use it accordingly within #Transaction
#Transactional("mysqlTx")
#Repository
public interface UserMysqlDao extends CrudRepository<UserMysql, Integer>{
public UserMysql findByName(String name);
}
Thanks all for your help but it is not complicated as it seems; almost everything is handled internally by SpringBoot.
In my case I want to use Mysql and Mongodb and the solution was to use EnableMongoRepositories and EnableJpaRepositories annotations on to my application class.
#SpringBootApplication
#EnableTransactionManagement
#EnableMongoRepositories(includeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository))
#EnableJpaRepositories(excludeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository))
class TestApplication { ...
NB: All mysql entities have to extend JpaRepository and mongo enities have to extend MongoRepository.
The datasource configs are straight forward as presented by spring documentation:
//mysql db config
spring.datasource.url= jdbc:mysql://localhost:3306/tangio
spring.datasource.username=test
spring.datasource.password=test
#mongodb config
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=tangio
spring.data.mongodb.username=tangio
spring.data.mongodb.password=tangio
spring.data.mongodb.repositories.enabled=true
once you start work with jpa and some driver is in your class path spring boot right away puts it inside as your data source (e.g h2 )
for using the defult data source therefore u will need only to define
spring.datasource.url= jdbc:mysql://localhost:3306/
spring.datasource.username=test
spring.datasource.password=test
if we go one step farther and u want to use two
I would reccomend to use two data sources such as explained here :
Spring Boot Configure and Use Two DataSources
MySqlBDConfig.java
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "PACKAGE OF YOUR CRUDS USING MYSQL DATABASE",entityManagerFactoryRef = "mysqlEmFactory" ,transactionManagerRef = "mysqlTransactionManager")
public class MySqlBDConfig{
#Autowired
private Environment env;
#Bean(name="mysqlProperities")
#ConfigurationProperties(prefix="spring.mysql")
public DataSourceProperties mysqlProperities(){
return new DataSourceProperties();
}
#Bean(name="mysqlDataSource")
public DataSource interfaceDS(#Qualifier("mysqlProperities")DataSourceProperties dataSourceProperties){
return dataSourceProperties.initializeDataSourceBuilder().build();
}
#Primary
#Bean(name="mysqlEmFactory")
public LocalContainerEntityManagerFactoryBean mysqlEmFactory(#Qualifier("mysqlDataSource")DataSource mysqlDataSource,EntityManagerFactoryBuilder builder){
return builder.dataSource(mysqlDataSource).packages("PACKAGE OF YOUR MODELS").build();
}
#Bean(name="mysqlTransactionManager")
public PlatformTransactionManager mysqlTransactionManager(#Qualifier("mysqlEmFactory")EntityManagerFactory factory){
return new JpaTransactionManager(factory);
}
}
H2DBConfig.java
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "PACKAGE OF YOUR CRUDS USING MYSQL DATABASE",entityManagerFactoryRef = "dsEmFactory" ,transactionManagerRef = "dsTransactionManager")
public class H2DBConfig{
#Autowired
private Environment env;
#Bean(name="dsProperities")
#ConfigurationProperties(prefix="spring.h2")
public DataSourceProperties dsProperities(){
return new DataSourceProperties();
}
#Bean(name="dsDataSource")
public DataSource dsDataSource(#Qualifier("dsProperities")DataSourceProperties dataSourceProperties){
return dataSourceProperties.initializeDataSourceBuilder().build();
}
#Bean(name="dsEmFactory")
public LocalContainerEntityManagerFactoryBean dsEmFactory(#Qualifier("dsDataSource")DataSource dsDataSource,EntityManagerFactoryBuilder builder){
LocalContainerEntityManagerFactoryBean em = builder.dataSource(dsDataSource).packages("PACKAGE OF YOUR MODELS").build();
HibernateJpaVendorAdapter ven = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(ven);
HashMap<String, Object> prop = new HashMap<>();
prop.put("hibernate.dialect", env.getProperty("spring.jpa.properties.hibernate.dialect"));
prop.put("hibernate.show_sql", env.getProperty("spring.jpa.show-sql"));
em.setJpaPropertyMap(prop);
em.afterPropertiesSet();
return em;
}
#Bean(name="dsTransactionManager")
public PlatformTransactionManager dsTransactionManager(#Qualifier("dsEmFactory")EntityManagerFactory factory){
return new JpaTransactionManager(factory);
}
}
application.properties
#---mysql DATASOURCE---
spring.mysql.driverClassName = com.mysql.jdbc.Driver
spring.mysql.url = jdbc:mysql://127.0.0.1:3306/test
spring.mysql.username = root
spring.mysql.password = root
#----------------------
#---H2 DATASOURCE----
spring.h2.driverClassName = org.h2.Driver
spring.h2.url = jdbc:h2:file:~/test
spring.h2.username = root
spring.h2.password = root
#---------------------------
#------JPA-----
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
Application.java
#SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ac=SpringApplication.run(KeopsSageInvoiceApplication.class, args);
UserMysqlDao userRepository = ac.getBean(UserMysqlDao.class)
//for exemple save a new user using your repository
userRepository.save(new UserMysql());
}
}
I have problem with displaying error message in spring Application.i am using Spring MVC 3 and Apache Tiles. when i am having error in form than it will not displays error message.
please help me hear is the piece of code.
Web.xml
<?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">
<display-name>SpringExample</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>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/dispatcher-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
dispatcher-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"
xmlns:p="http://www.springframework.org/schema/p"
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">
<context:component-scan base-package="com.examples.spring" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
</beans>
tiles.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="create_account_success" template="/WEB-INF/jsp/account/SuccessJSP.jsp">
</definition>
<definition name="account_create" template="/WEB-INF/jsp/account/testForm.jsp">
</definition>
</tiles-definitions>
testForm.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form:form id="form" modelAttribute="formCreate" method="post">
<table>
<tr>
<td>Name :</td>
<td><form:input path="name"/>
<form:errors path="name"/>
</td>
</tr>
<tr>
<td>Password :</td>
<td><form:input path="password"/>
<form:errors path="password"/>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" /></td>
</tr>
</table>
</form:form>
</body>
</html>
AccountRegistrationController.java
package com.examples.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.examples.spring.dto.AccountDTO;
import com.examples.spring.validator.AccountValidator;
#Controller
public class AccountRegistrationController {
public static final String BASE_URL = "/account";
#RequestMapping(value = BASE_URL + "/create" ,method = RequestMethod.GET)
public ModelAndView accountCreate(){
ModelAndView view = new ModelAndView();
view.addObject("formCreate", new AccountDTO());
view.setViewName("account_create");
return view;
}
#RequestMapping(value = BASE_URL + "/create" ,method = RequestMethod.POST)
public ModelAndView accountRegistration(#ModelAttribute AccountDTO accountDTO,BindingResult result ){
ModelAndView view = new ModelAndView();
AccountValidator validator = new AccountValidator();
validator.validate(accountDTO, result);
if (result.hasErrors()) {
view.setViewName("account_create");
view.addObject("formCreate", accountDTO);
return view;
}
view.setViewName("create_account_success");
return view;
}
#RequestMapping(value = BASE_URL + "/login" ,method = RequestMethod.GET)
public ModelAndView accountLogin(){
ModelAndView view = new ModelAndView();
view.setViewName("account_login");
return view;
}
}
AccountValidator.java
package com.examples.spring.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.examples.spring.dto.AccountDTO;
public class AccountValidator implements Validator {
#Override
public boolean supports(Class<?> clazz) {
return AccountDTO.class.isAssignableFrom(clazz);
}
#Override
public void validate(Object result, Errors error) {
AccountDTO accountDTO = (AccountDTO) result;
ValidationUtils.rejectIfEmpty(error, "name", "require.name", "Name Requires.");
ValidationUtils.rejectIfEmpty(error, "password", "require.password", "Password Requires.");
}
}
AccountDTO.java
package com.examples.spring.dto;
public class AccountDTO {
private String name;
private String password;
public AccountDTO() {
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
My Code is working well but it does not displays error messages in <form:errors />.
please help me.
The third parameter to ValidationUtils.rejectIfEmpty is an error code. It should be a key to the actual message in your resource bundle. I don't know how it behaves if it can't find a value. You should change it to use a key, and optionally set a default message. See the api.
You need to register your validator with the controller in which you want to use it. See: http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html#validation.mvc