Spring MVC 3 Validator not displaying Error Message - java

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

Related

Spring MVC Simple controller example

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");
}
}

Execution of Struts basic application getting java.lang.NoSuchMethodException

I'm new to struts framework. So seeking some online tutorials and tried to develop a very basic application. But I'm unable to run it properly
after clicking button action method "execute()" was unable to locate
by container.
I am not getting what I'm missing.
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>SampleApplication</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>sample</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>sample</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<!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>Sample Struts Application</title>
</head>
<body>
<s:form action="invoke">
<s:textfield name="name" label="UserName"></s:textfield><br>
<s:password name="password" label="Password"></s:password><br>
<s:submit value="GO"></s:submit>
</s:form>
</body>
</html>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="helloworld" extends="struts-default"><action name="invoke" class="com.techm.SampleStruts" method="execute">
<result name="success">/Success.jsp</result>
</action>
</package></struts>
SampleStruts.java
import com.opensymphony.xwork2.ActionSupport;
public class SampleStruts extends ActionSupport{
private static final long serialVersionUID = 1L;
String name, 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;
}
public String execute()
{
return "success";
}
}
Jars used are :
commons-logging-1.0.4.jar
freemarker-2.3.8.jar
ognl-2.6.11.jar
servlet-api-2.5.jar
struts2-core-2.0.11.jar
StrutsInterceptors.rar
xwork-2.0.4.jar
Stack trace :
java.lang.NoSuchMethodException: com.techm.SampleStruts.execute()
at java.lang.Class.getMethod(Unknown Source)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:55)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:41)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223)
at com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:83)
at com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224)
Finally i found the solution is that , after adding .action to the action value.
it is working fine.
<s:form action="invoke.action">
<s:textfield name="name" label="UserName"></s:textfield><br>
<s:password name="password" label="Password"></s:password><br>
<s:submit value="GO"></s:submit>

Spring MVC form error

I am trying to run a project in Spring MVC. Here is the code
index.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#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=UTF-8">
<title>Welcome to Spring Web MVC project</title>
</head>
<body>
<h1>Spring 3 Register!</h1>
click
<form:form action="${pageContext.request.contextPath}/register" method="POST" modelAttribute="userForm">
<table>
<tr>
<td colspan="2" align="center">Spring MVC Form Demo - Registration</td>
</tr>
<tr>
<td>User Name</td>
<td><form:input path="username" /></td>
</tr>
<tr>
<td>Password</td>
<td><form:password path="password" /></td>
</tr>
<tr>
<td>Email</td>
<td><form:input path="email" /></td>
</tr>
<tr>
<td>BirthDate (mm/dd/yyyy)</td>
<td><form:input path="birthDate" /></td>
</tr>
<tr>
<td>Profession</td>
<td><form:select path="profession" items="${professionList}" /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Register" /></td>
</tr>
</table>
</form:form>
</body>
</html>
RegistrationController.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package RegisterInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*
* #author Harshit Shrivastava
*/
import RegisterInfo.model.User;
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.RequestMethod;
import org.springframework.ui.Model;
#Controller
#RequestMapping(value = "/register")
public class RegistrationController {
#RequestMapping(method = RequestMethod.GET)
public String viewRegistration(Model model)
{
User userForm = new User();
model.addAttribute("userForm", new User());
/*List<String> professionList = new ArrayList();
professionList.add("Developer");
professionList.add("Designer");
professionList.add("IT Manager");
model.put("professionList", professionList);*/
return "index";
}
#RequestMapping(method = RequestMethod.POST)
public String processRegistration(#ModelAttribute("userForm") User user, Map<String, Object> model)
{
System.out.println("Username : " + user.getUserName());
model.put("userForm", new User());
return "index";
}
}
User.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package RegisterInfo.model;
/**
*
* #author Harshit Shrivastava
*/
import java.util.Date;
public class User {
private String username;
private String password;
private String email;
private Date birthDate;
private String profession;
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 String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public Date getBirthDate()
{
return birthDate;
}
public void setBirthDate(Date birthDate)
{
this.birthDate = birthDate;
}
public String getProfession()
{
return profession;
}
public void setProfession(String profession)
{
this.profession = profession;
}
}
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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd ">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<context:component-scan base-package="SpringRegister" />
<mvc:annotation-driven />
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.htm">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
In the above program, Whenever I go to http://localhost:8080/SpringRegister/index.htm, I always gets this error
Error:
neither bindingresult nor plain target object for bean 'userForm' available as request attribute
What is wrong with the code?
When you hit the http://localhost:8080/SpringRegister/index.htm from browser, Your request is handled by ParameterizableViewController which does not set the model attribute (userForm) and forwards to index.jsp, the index.jsp's form tag expects the model attribute userForm <form:form action="${pageContext.request.contextPath}/register" method="POST" modelAttribute="userForm"> , which is not available. that why the error. To resolve this you can create your own conrtoller which handles your http://localhost:8080/SpringRegister/index.htm URL,
ModelAndView modelAndView = new ModelAndView("your view name");
model.addAttribute("userForm", new User());
configure that controller instead of class="org.springframework.web.servlet.mvc.ParameterizableViewController" in your servlet xml. Hope this helps.
You need to Change in Controller To bind userForm with Bean ----
Jsp Form --
<form:form action="userAction" modelAttribute="userForm " class="form-search" role="form">
Controller --
#RequestMapping (value = "/userAction")
public ModelAndView checkFeasibility(#ModelAttribute("userForm ")User userForm)
{
// Any Action
model.addObject("userForm",userForm);
return model;
}
In order to Bind userForm modelAttribute of form with User Bean.

My Spring Application could not load the Servlet Context

I am working on the Spring4.1.6 release. I have deployed my Webapplication named SpringMVCTest on Tomcat 7.0. I am getting the below exception on the tomcat startup. Below are the spring configuration file details.
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_3_0.xsd"
version="3.0">
<display-name>SpringMVC Test Web Application</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
I have already added the contextConfigLocation parameter inside the web.xml and also below is the contents of the webmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-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/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Scans within the base package of the application for #Components to configure as beans -->
<!-- #Controller, #Service, #Configuration, etc. -->
<context:component-scan base-package="com.springmvc" />
<!-- Enables the Spring MVC #Controller programming model -->
<mvc:annotation-driven />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
Bean class
/**
*
*/
package com.springmvc.bean.Person;
import java.util.List;
/**
* #author jp48346
*
*/
public class Person {
private String name;
private String email;
private String gender;
private String password;
private String passwordConf;
private List<String> courses;
private String tutor;
private String hiddenMessage;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordConf() {
return passwordConf;
}
public void setPasswordConf(String passwordConf) {
this.passwordConf = passwordConf;
}
public List<String> getCourses() {
return courses;
}
public void setCourses(List<String> courses) {
this.courses = courses;
}
public String getTutor() {
return tutor;
}
public void setTutor(String tutor) {
this.tutor = tutor;
}
public String getHiddenMessage() {
return hiddenMessage;
}
public void setHiddenMessage(String hiddenMessage) {
this.hiddenMessage = hiddenMessage;
}
}
PersonRegistration.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"%>
<!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>test Spring MVC Sample</title>
</head>
<body>
<h2>Fill your form!</h2>
<form:form method="POST" commandName="form">
<table>
<tr>
<td>Enter your name:</td>
<td><form:input path="name" /></td>
<td><form:errors path="name" cssStyle="color: #ff0000;"/></td>
</tr>
<tr>
<td><input type="submit" name="submit" value="Submit"></td>
</tr>
</table>
</form:form>
</body>
</html>
But I don't understand one thing why I am still getting the below exception? As per the logs why it is still trying to look for the applicationContext.xml in the WEB-INF directory? Please help me on this issue and do let me know if any other information is required to resolve the issue.
INFO: Loading XML bean definitions from ServletContext resource
[/WEB-INF/applicationContext.xml] May 19, 2015 6:36:01 PM
org.springframework.web.context.ContextLoader
initWebApplicationContext SEVERE: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from ServletContext resource
[/WEB-INF/applicationContext.xml]; nested exception is
java.io.FileNotFoundException: Could not open ServletContext resource
[/WEB-INF/applicationContext.xml] at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:344)
at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:304)
at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:181)
at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:217)
at
org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:188)
at
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at
org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at
org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:537)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:452)
at
org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5016)
at
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5528)
at
org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
at
org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
at java.util.concurrent.FutureTask.run(FutureTask.java:262) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745) Caused by:
java.io.FileNotFoundException: Could not open ServletContext resource
[/WEB-INF/applicationContext.xml] at
org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
at
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330)
... 21 more

Spring Boot Multiple Datasource

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());
}
}

Categories