I'm trying to validate a form using Spring WebFlow and Hibernate Validator Annotations, but I'm doing something wrong.
If I use the Spring validation way (ValidationContext, MessageContext, validate${state}, etc), all works fine, but I want to use the Hibernate Annotations like #Email, #NotEmpty, etc.
I've read a lot of forums, Spring documentation, but I don't know what I'm doing wrong.
At this moment, this is my view-state and next action code:
<var name="user" class="myproject.web.pojo.User"/>
<view-state id="startSignup" model="user">
<binder>
<binding property="email" />
<binding property="name" />
<binding property="lastName" />
<binding property="password" />
</binder>
<on-entry>
<set name="flowScope.user" value="new info.teaming.web.pojo.User()" />
</on-entry>
<transition on="dataEntered" to="lookupUser" />
</view-state>
<action-state id="lookupUser">
<evaluate expression="signupActions.lookupUser(user)" />
<transition to="startSignup" on-exception="myproject.web.service.exception.UserAlreadyExistsException" />
<transition to="saveOrder" />
</action-state>
(...)
This is the startSignup.jsp code:
<!-- sf:form method="POST" modelAttribute="user" -->
<sf:form method="POST" commandName="user" >
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}" />
<fieldset>
<table cellspacing="0">
<tr>
<th>
<label for="name"><fmt:message key="signUp.name"/></label>
</th>
<td>
<sf:input path="name" size="25" id="name" />
</td>
<sf:errors path="name" />
</tr>
<tr>
<th>
<label for="lastName"><fmt:message key="signUp.lastName"/></label>
</th>
<td>
<sf:input path="lastName" size="45" maxlength="45" id="lastName" />
</td>
</tr>
<tr>
<th>
<label for="password"><fmt:message key="signUp.password"/></label>
</th>
<td>
<sf:password path="password" size="20" showPassword="true" id="password" />
</td>
</tr>
<tr>
<th>
<label for="email"><fmt:message key="signUp.email"/></label>
</th>
<td>
<sf:input path="email" size="30" id="email" />
</td>
</tr>
<tr>
<td>
<input type="submit" name="_eventId_dataEntered" value="<fmt:message key="signUp.register"/>"/>
</td>
</tr>
</table>
</fieldset>
</sf:form>
This is the myproject.web.pojo.User POJO code:
import java.io.Serializable;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#NotEmpty
#Length(min = 2, max = 25)
private String name;
#NotEmpty
#Email
private String email;
#NotEmpty
#Length(min = 2, max = 45)
private String lastName;
#NotEmpty
#Length(min = 6, max = 20)
private String password;
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 void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
// public void validateStartSignup(ValidationContext context) {
// MessageContext messages = context.getMessageContext();
//
// messages.addMessage(new MessageBuilder().error().source("name").code("user.name.notEmpty").build());
// }
}
(note: as you can see, when I work with Spring Validation (uncomment the validate method), the form validates successfully)
And finally, this is my SignupAction code:
import myproject.web.model.UsrUser;
import myproject.web.model.dao.UsrUserDAO;
import myproject.web.pojo.User;
import myproject.web.service.exception.UserAlreadyExistsException;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.stereotype.Component;
import org.springframework.webflow.action.MultiAction;
import org.springframework.webflow.execution.Event;
#Component
public class SignupActions extends MultiAction {
#Resource
UsrUserDAO usrUserDAO;
private static final long serialVersionUID = 1L;
public Event lookupUser(#Valid User user) throws UserAlreadyExistsException {
try {
usrUserDAO.findByEmail(user.getEmail());
} catch (javax.persistence.NoResultException e) {
return success();
}
throw new UserAlreadyExistsException();
}
public void saveUser(UsrUser user) {
return;
}
}
When I work with Hibernate Validation, the flow arrives to the saveUser method, without any validation.
I'm using Spring 3:
Spring 3.0.5.RELEASE
Spring WebFlow 2.2.1.RELEASE
Hibernate Validator 4.0.2.GA
What I'm doing wrong?
Thanks a lot for helping me! :)
have you defined your validator in Spring configuration XML file?
According to Spring Webflow reference it shoud be defined like this:
<webflow:flow-registry flow-builder-services="flowBuilderServices" />
<webflow:flow-builder-services id="flowBuilderServices" validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
Try,
Changing:
#Resource
UsrUserDAO usrUserDAO;
By:
#Autowired
private UsrUserManager UsrUserManager;
Using MVC manager.
And:
#Transactional
public Event lookupUser(#Valid User user) throws UserAlreadyExistsException { ...
as a Spring MVC controller, or reusing this MVC code if you already desing it ;)
Related
I am new to spring and trying to Upload an image using spring 4.2.7 and commons-io-1.3.2,commons-fileupload-1.3,jdk 1.8.
But unfortunately I am getting error i.e HTTP Status 400 -The request sent by the client was syntactically incorrect.
Please help.
Code snippet is
formExamplePage.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>Spring Form Example</title>
</head>
<body>
<h2>Form Example</h2>
<form:form commandName="formExample" action="formExampleDetails" method="post">
<table>
<tr>
<td>
<label>User Name:</label>
</td>
<td>
<form:input path="userName" placeholder="User Name"></form:input>
</td>
</tr>
<tr>
<td>
<label>Salary:</label>
</td>
<td>
<form:input path="salary" placeholder="salary in decimal"/>
</td>
</tr>
<tr>
<td>
<label>Gender</label>
</td>
<td>
<form:radiobutton path="gender" value="M" label="Male"/>
<form:radiobutton path="gender" value="F" label="Female"/>
</td>
</tr>
<tr>
<td>
<label>Profile Photo:</label>
</td>
<td>
<input name="profilePhoto" type="file"/>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Submit"/>
</td>
<td>
<input type="reset" value="Reset">
</td>
</tr>
</table>
</form:form>
</body>
</html>
Controller class is ApplicationController.java
#Controller
public class ApplicationController {
#RequestMapping(value="/formExampleDetails",method=RequestMethod.POST)
public String formExampleDetails(#ModelAttribute FormExample formExample,
#RequestParam("profilePhoto") MultipartFile profilePhoto,ModelMap model){
System.out.println("User Name====>"+formExample.getUserName());
System.out.println("BirthDate====>"+formExample.getBirthDate());
System.out.println("Gender=======>"+formExample.getGender());
System.out.println("Salary=======>"+formExample.getSalary());
System.out.println("ProfilePhoto=>"+profilePhoto.getOriginalFilename());
return "index";
}
}
Pojo Class i.e FormExample.java is
package com.spring.pojo;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Date;
public class FormExample implements Serializable{
private static final long serialVersionUID = 5527691555730303451L;
private String userName;
private Date birthDate;
private BigDecimal salary;
private Blob profilePhoto;
private Character gender;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public BigDecimal getSalary() {
return salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Blob getProfilePhoto() {
return profilePhoto;
}
public void setProfilePhoto(Blob profilePhoto) {
this.profilePhoto = profilePhoto;
}
public Character getGender() {
return gender;
}
public void setGender(Character gender) {
this.gender = gender;
}
}
spring configuration file is
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.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.xsd">
<context:component-scan base-package="com.spring"></context:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="./"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"></property>
</bean>
</beans>
Have you seen this question on multipartFiles and blobs? Your form:form may require enctype="multipart/form-data" .
I haven't tried to run your code, but have you tried to either remove, rename profilePhoto and its getter and setter from FormExample, or set its type to MultipartFile ?
I suspect that despite your controller method having a parameter with the same name Spring might be trying to assign the parameter value to both the method parameter and the form property, and failing to convert MultipartFile to java.sql.Blob when assigning to the form property.
I am new to Spring security.
I have created a custom form that logs a user in and then, upon successful login, the user continues to his/her intended webpage. My implementation is standard and it works.
Here's my problem.
A user wants to go to page mywebpage.html.
The user is not logged in. The
user is redirected (by Spring Security) to the login page.
The user
does not have an account.
The user clicks on the createAccount link
and goes via standard MVC protocols to a registration page.
How do I now get the user's originally intended destination (mywebpage.html) from Spring Security, so I can redirect the user to that page once he/she has created an account?
For the record, security.xml
<http auto-config="true">
<intercept-url pattern="/login" access="permitAll()" />
<intercept-url pattern="/flow-entry.html" access="hasRole('ROLE_USER')"/>
<form-login
login-page="/login"
authentication-failure-url="/login?error=true" />
<logout logout-success-url="/login" />
</http>
login form
<form name='f' action="login" method='POST'>
<table style="text-align:left" class="w3-table" >
<tr style="text-align:center;color:red" th:if="${loginresponse}">
<td colspan="2" style="text-align:center" th:text="#{${loginresponse}}"> </td>
</tr>
<tr>
<td th:text="#{label.emaillogin}"></td>
<td><input type="text" name="username" value=''/></td>
</tr>
<tr>
<td th:text="#{label.password}">Password:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2" style="text-align:center"><input name="submit" type="submit" class="w3-btn w3-blue w3-hover-aqua w3-round-large" th:value="#{label.ok}" /></td>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</tr>
<tr style="text-align:center">
<td colspan="2" style="text-align:center"> <span th:text="#{label.register}"></span> </td>
</tr>
</table>
</form>
Controller Method. I need originally intended web page in this method
#RequestMapping(value = "/doRegistration", method=RequestMethod.POST)
public ModelAndView doRegistration(ModelAndView mv, HttpServletRequest request)
{
mv.setViewName("register");
SSm.getLogger().debug("registering new user");
String email = request.getParameter("username");
String email1 = request.getParameter("username1");
if(email.equals(email1))
{
if(email.contains("#")&&email.contains("."))
{
SSm.getLogger().debug("got legit email");
String password = request.getParameter("password");
String password1 = request.getParameter("password1");
if(password.equals(password1))
{
SSm.getLogger().debug("ready to login");
I NEED USERS ORIGINALLY INTENDED DESTINATION RIGHT HERE SO I CAN SET THE VIEW
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.passwordmismatch");
}
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.invalidemail");
}
}
else
{
mv.setViewName("register");
mv.addObject("loginresponse", "message.emailmismatch");
}
return mv;
}
You could use a SavedRequestAwareAuthenticationSuccessHandler.
When a non authorized request reaches the ExceptionTranslationFilter, a RequestCache of class HttpSessionRequestCache is created and the original request is saved on it.
This way, if you do not set alwaysUseDefaultTargetUrl to true, httpRequest would be reconstructed and used as target url while correct login is performed.
So, try to #Autowire (I use #Resource instead as I have more than one AuthenticationManager and AuthenticationSuccessHandler in my security config) the AuthenticationSuccessHandler in your controller and calling determineTargetUrl() like this:
I made a little modifications such as use #Valid annotations and implement a Validator to validate the registration form
Security.xml
<beans:bean id="savedRequestSuccesHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/zone4/secured/securedPage.htm" />
</beans:bean>
<security:http pattern="/zone4/**" use-expressions="true" authentication-manager-ref="mainAuthenticationManager">
<security:intercept-url pattern="/zone4/simple/**" access="permitAll()" />
<security:intercept-url pattern="/zone4/secured/**" access="isAuthenticated()"/>
<security:form-login
login-page="/zone4/simple/login.htm"
authentication-failure-url="/login.htm?error=true"
authentication-success-handler-ref="savedRequestSuccesHandler"
username-parameter="email"
password-parameter="password"
login-processing-url="/zone4/secured/performLogin.htm"
/>
<security:logout
logout-url="/zone4/secured/performLogout.htm"
logout-success-url="/zone4/simple/login.htm" />
<security:csrf disabled="true"/>
</security:http>
Controller:
/**
*
*/
package com.eej.ssba2.controller.test;
import java.io.IOException;
import java.util.Arrays;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
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 com.eej.ssba2.model.test.zone4.RegisterModel;
import com.eej.ssba2.model.test.zone4.RegisterModelValidator;
/**
*
*/
#Controller
#RequestMapping("/zone4")
public class Zone4TestController {
private Logger logger = Logger.getLogger(this.getClass());
#Resource(name="mainAuthenticationManager")
private AuthenticationManager authenticationManager;
#Resource(name="savedRequestSuccesHandler")
private SavedRequestAwareAuthenticationSuccessHandler successHandler;
#RequestMapping("/simple/unsecuredPage.htm")
public String unsecuredPage(){
return "simple/unsecuredPage";
}
#RequestMapping("/secured/securedPage.htm")
public String securedPage1(){
return "simple/secured/securedPage";
}
#RequestMapping("/secured/securedPage2.htm")
public String securedPage2(){
return "simple/secured/securedPage2";
}
#RequestMapping("/secured/securedPage3.htm")
public String securedPage3(){
return "simple/secured/securedPage3";
}
#RequestMapping("/simple/login.htm")
public String login(){
return "simple/login/login";
}
#RequestMapping(value="/simple/register.htm", method=RequestMethod.GET)
public String register(ModelMap model){
logger.debug("Entrada en register.htm");
if(!model.containsAttribute("registerModel")){
model.addAttribute("registerModel", new RegisterModel());
}
return "simple/login/register";
}
#RequestMapping(value="/simple/register.htm", method=RequestMethod.POST)
public String register(
HttpServletRequest request, HttpServletResponse response,
#Valid RegisterModel registerModel, ModelMap model, BindingResult bindingResult){
logger.info("entrada en register");
RegisterModelValidator userValidator = new RegisterModelValidator();
userValidator.validate(registerModel, bindingResult);
if(bindingResult.hasErrors()){
logger.info("BindingResult has errors: " + bindingResult.getAllErrors());
model.addAttribute("errors", bindingResult.getAllErrors());
model.addAttribute("registerModel", registerModel);
return "simple/login/register";
}
// Your user register business
Authentication authenticated = null;
/*
* If the user is created at this time due to your business logic, you could authenticate it directly
* through the manager
*
authenticated =
this.authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
registerModel.getMail1(),
registerModel.getPassword1()
)
);
*/
authenticated = new UsernamePasswordAuthenticationToken(
registerModel.getMail1(),
registerModel.getPassword1(),
Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))
);
SecurityContextHolder.getContext().setAuthentication(authenticated);
try {
this.successHandler.onAuthenticationSuccess(request, response, authenticated);
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Registration model bean:
package com.eej.ssba2.model.test.zone4;
import java.io.Serializable;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import org.apache.log4j.Logger;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.eej.ssba2.ApplicationVersion;
/**
*
*
*/
public class RegisterModel implements Serializable{
private Logger logger = Logger.getLogger(this.getClass());
/**
*
*/
private static final long serialVersionUID = 1L;
#NotEmpty
#Pattern(regexp = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*" +
"#[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$|")
public String mail1;
#NotEmpty
#Pattern(regexp = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*" +
"#[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$|")
public String mail2;
#NotEmpty
public String password1;
#NotEmpty
public String password2;
// getters and setters
}
The Validator imiplementation I use to validate the fields in the model:
package com.eej.ssba2.model.test.zone4;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class RegisterModelValidator implements Validator {
#Override
public boolean supports(Class<?> arg0) {
return RegisterModel.class.equals(arg0);
}
#Override
public void validate(Object target, Errors errors) {
RegisterModel user = (RegisterModel) target;
if(!user.getMail1().equals(user.getMail2())){
errors.rejectValue("mail1", "lbl_mail1_and_mail2_must_be_equal");
errors.rejectValue("mail2", "lbl_mail1_and_mail2_must_be_equal");
}
if(!user.getPassword1().equals(user.getPassword2())){
errors.rejectValue("password1", "lbl_pass1_and_pass2_must_be_equal");
errors.rejectValue("password2", "lbl_pass1_and_pass2_must_be_equal");
}
}
Finally, the registration jsp:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%# 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>Login</title>
</head>
<body>
<form:form role="registerModel" commandName="registerModel" method="POST" action="${pageContext.request.contextPath}/zone4/simple/register.htm">
<form:errors path="*" cssClass="errorblock" element="div" />
<fieldset>
<div class="form-group">
<form:input path="mail1" id="mail1" name="mail1" placeHolder="email" />
<form:errors path="mail1" id="mail1" name="mail1" placeHolder="email" cssClass="error" />
</div>
<div class="form-group">
<form:input path="mail2" id="mail2" name="mail2" placeHolder="email" />
<form:errors path="mail2" id="mail2" name="mail2" placeHolder="email" cssClass="error" />
</div>
<div class="form-group">
<form:input path="password1" id="password1" name="password1" placeHolder="password" />
<form:errors path="password1" id="password1" name="password1" placeHolder="password" cssClass="error" />
</div>
<div class="form-group">
<form:input path="password2" id="password2" name="password2" placeHolder="password" />
<form:errors path="password2" id="password2" name="password2" placeHolder="password" cssClass="error" />
</div>
<div class="checkbox">
<label>
<input name="remember-me" id="remember-me" type="checkbox" value="Remember Me">Remember Me
</label>
</div>
<!-- Change this to a button or input when using this as a form -->
<button type="submit" class="btn btn-lg btn-success btn-block" name="submit"><spring:message code="lblRegistration"/></button>
</fieldset>
</form:form>
</body>
</html>
Issue:
org.springframework.beans.NotReadablePropertyException: Invalid property 'Orgaddress' of bean class
[com.techvision.studycenter.model.Organization]: Bean property 'Orgaddress' is not readable or has an invalid getter method:
Does the return type of the getter match the parameter type of the setter?
OrgController.java
package com.techvision.studycenter.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
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.techvision.studycenter.model.Organization;
import com.techvision.studycenter.service.OrgService;
#Controller
public class OrgController {
#Autowired
private OrgService orgService;
#RequestMapping(value="/login")
public ModelAndView home(){
return new ModelAndView("OrgList", "command", new Organization());
}
#RequestMapping(value="/saveOrg")
public ModelAndView saveOrg(#ModelAttribute("orgnew")Organization organization)
{
orgService.saveOrg(organization);
return new ModelAndView("redirect:/add.html");
}
#RequestMapping(value = "/add", method = RequestMethod.GET)
public ModelAndView addEmployee(#ModelAttribute("orgnew")Organization organization,
BindingResult result) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("orgLists", orgService.listOrgs());
return new ModelAndView("orgList", model);
}
}
OrgService.java
package com.techvision.studycenter.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.techvision.studycenter.model.Organization;
public interface OrgService {
void saveOrg(Organization organization);
List<Organization> listOrgs();
}
OrgServiceImpl.java
package com.techvision.studycenter.service;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.techvision.studycenter.model.Organization;
#Service("OrgService")
#Transactional
public class OrgSerivceImpl implements OrgService {
#Autowired
private SessionFactory sessionFactory;
#Override
public void saveOrg(Organization organization) {
// TODO Auto-generated method stub
System.out.println("i am at service");
sessionFactory.getCurrentSession().saveOrUpdate(organization);
}
#Override
public List<Organization> listOrgs() {
// TODO Auto-generated method stub
return (List<Organization>) sessionFactory.getCurrentSession().createCriteria(Organization.class).list();
}
}
JPA entities
Organization.java
package com.techvision.studycenter.model;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
import java.math.BigInteger;
import java.util.Set;
/**
* The persistent class for the organization database table.
*
*/
#Entity
#Table(name="organization")
#NamedQuery(name="Organization.findAll", query="SELECT o FROM Organization o")
public class Organization implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private long orgid;
#Temporal(TemporalType.TIMESTAMP)
private Date dateofcreation;
#Column(length=45)
private String orgcode;
#Column(length=45)
private String orgmode;
#Column(length=45)
private String orgname;
private long orgparent;
#Column(length=1)
private char orgstatus;
//bi-directional many-to-one association to Degreecategory
#OneToMany(mappedBy="organization")
private Set<Degreecategory> degreecategories;
//bi-directional many-to-one association to Medium
#OneToMany(mappedBy="organization")
private Set<Medium> mediums;
//bi-directional many-to-one association to Orgaddress
#OneToMany(mappedBy="organization")
private Set<Orgaddress> orgaddresses;
//bi-directional many-to-one association to Person
#OneToMany(mappedBy="organization")
private Set<Person> persons;
//bi-directional many-to-one association to Yearname
#OneToMany(mappedBy="organization")
private Set<Yearname> yearnames;
public Organization() {
}
//getter and setter methods...
}
OrgAddress.java
package com.techvision.studycenter.model;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
/**
* The persistent class for the orgaddress database table.
*
*/
#Entity
#Table(name="orgaddress")
#NamedQuery(name="Orgaddress.findAll", query="SELECT o FROM Orgaddress o")
public class Orgaddress implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(unique=true, nullable=false)
private long orgaddressid;
#Column(length=100)
private String address1;
#Column(length=100)
private String address2;
#Column(length=100)
private String city;
#Column(length=45)
private String country;
#Temporal(TemporalType.TIMESTAMP)
private Date dateofcreation;
#Column(length=200)
private String emailid1;
#Column(length=200)
private String emailid2;
#Column(length=45)
private String fax;
#Column(length=45)
private String landlinenumber;
#Column(length=100)
private String location;
#Column(length=45)
private String mobilenumber;
#Column(length=45)
private String orgaddresscol;
#Column(length=1)
private char orgaddressstatus;
#Column(length=45)
private String postalcode;
#Column(length=45)
private String state;
//bi-directional many-to-one association to Organization
#ManyToOne
#JoinColumn(name="orgid", nullable=false)
private Organization organization;
public Orgaddress() {
}
//getter and setter method...
}
OrgList.jsp
<form:input path="orgcode" id="orgcode" name="orgcode" type="text" placeholder="Org Code" class="form-control input-md"/>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Street1</label>
<div class="col-md-4">
<form:input path="Orgaddress.address1" id="Orgaddress.address1" type="text" placeholder="placeholder" class="form-control input-md"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Street 2</label>
<div class="col-md-4">
<form:input path="Orgaddress.address2" id="Orgaddress.address2" name="Orgaddress.address2" type="text" placeholder="placeholder" class="form-control input-md"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">City</label>
<div class="col-md-4">
<form:input path="orgaddresses.city" id="orgaddresses.city" name="city" type="text" placeholder="placeholder" class="form-control input-md"/>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Country</label>
<div class="col-md-4">
<form:input path="orgaddresses.country" id="orgaddresses.country" name="orgaddressescountry" type="text" placeholder="placeholder" class="form-control input-md"/>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-4 control-label" for="singlebutton">Single Button</label>
<div class="col-md-4">
<button id="singlebutton" name="singlebutton" class="btn btn-primary">Button</button>
</div>
</div>
</fieldset>
</form:form>
spring-servlet.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"
xmlns:tx="http://www.springframework.org/schema/tx"
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.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<!-- <context:property-placeholder location="classpath:resources/database.properties"> </context:property-placeholder> -->
<context:property-placeholder location="classpath:resources/database.properties"/>
<!-- It register the beans in context and scan the annotations inside beans and activate them -->
<context:component-scan base-package="com.techvision.studycenter" />
<mvc:resources mapping="/resources/**" location="/resources/mytheme/" />
<!-- This allow for dispatching requests to Controllers by registering
two beans - DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter -->
<mvc:annotation-driven />
<!-- This helps in mapping the logical view names to directly view files under a certain pre-configured directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- This resolves messages from resource bundles for different locales -->
<!-- <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean> -->
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${database.driver}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.user}"></property>
<property name="password" value="${database.password}"></property>
</bean>
<bean class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" id="sessionFactory">
<property name="dataSource" ref="dataSource"></property>
<property name="annotatedClasses">
<list>
<value>com.techvision.studycenter.model.Orgaddress</value>
<value>com.techvision.studycenter.model.Organization</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto} </prop>
</props>
</property>
</bean>
<bean class="org.springframework.orm.hibernate3.HibernateTransactionManager" id="hibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
Put your organization model
public String getPrivacyname()
{
String address1=null;
if (orgaddresses != null )
{
List<Orgaddress> orgAddresses= new ArrayList(getOrgaddresses());
if(orgAddresses!=null)
{
for(Orgaddress OrgAddress : orgAddresses){
address1= OrgAddress.getAddress1();
}
}
}
return address1;
}
I am trying to do validation in spring mvc. I have added the hibernate-validator-4.0.2.GA. jar and validation-api-1.0.0GA.jar but i am getting exception
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:141)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:174)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:194)
org.springframework.web.servlet.tags.form.LabelTag.autogenerateFor(LabelTag.java:129)
org.springframework.web.servlet.tags.form.LabelTag.resolveFor(LabelTag.java:119)
org.springframework.web.servlet.tags.form.LabelTag.writeTagContent(LabelTag.java:89)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:102)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:79)
org.apache.jsp.WEB_002dINF.jsp.contact_jsp._jspx_meth_form_005flabel_005f0(contact_jsp.java:250)
org.apache.jsp.WEB_002dINF.jsp.contact_jsp._jspService(contact_jsp.java:103)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1060)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:798)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:745)
org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:716)
org.apache.jsp.index_jsp._jspService(index_jsp.java:71)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Contact.jsp
<form:form method="get" action="addContact.html" modelAttribute="contact">
<table>
<tr>
<td><form:label path="firstname">First Name</form:label></td>
<td><form:input path="firstname" /></td>
<form:errors path="firstname"></form:errors>
</tr>
<tr>
<td><form:label path="lastname">Last Name</form:label></td>
<td><form:input path="lastname" /></td>
<form:errors path="lastname"></form:errors>
</tr>
<tr>
<td><form:label path="email">Email</form:label></td>
<td><form:input path="email" /></td>
<form:errors path="email"></form:errors>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Contact"/>
</td>
</tr>
</table>
Contact.java
public class Contact {
#NotEmpty
private String firstname = null;
#NotEmpty
private String lastname = null;
#NotEmpty
private String email=null;
/*#NotEmpty
#Min(1)
#Max(110)
private int telephone*/;
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;
}
}
ContactController.java
#Controller
#SessionAttributes
public class ContactController {
#RequestMapping(value = "/addContact", method = RequestMethod.GET)
public String addContact( #Valid #ModelAttribute("contact")
Contact contact, BindingResult
result,ModelMap model){
model.addAttribute("contact", new Contact());
if(result.hasErrors()) {
System.out.println("Hiii i am validator");
return "contact";
}
model.addAttribute("message", "Successfully saved person: " + contact.toString());
model.addAttribute("name",contact.getFirstname());
model.addAttribute("surname",contact.getLastname());
// model.addAttribute("age",contact.getTelephone());
model.addAttribute("email",contact.getEmail());
System.out.println("First Name:" + contact.getFirstname() +
"Last Name:" + contact.getLastname());
return "result";
}
#RequestMapping("/contacts")
public ModelAndView showContacts() {
return new ModelAndView("contact", "command", new Contact());
}
}
web.xml
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
spring-servlet.xml
<context:component-scan base-package="com.demo.Controller" />
<mvc:annotation-driven />
<context:annotation-config />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
</bean>
I have also tried using commandName instead of modelattribute but still i get the same exception and also tried using both get and post methods.
1 - Create a new Contact instance before loading your Contact.jsp
#RequestMapping("/contacts")
public ModelAndView showContacts() {
ModelAndView m = new ModelAndView("contact");
m.add("contact", new Contact());
return m;
}
2 - Ensure you are invoking the right servlet path :
#RequestMapping(value = "/addContact", method = RequestMethod.GET)
and change it in you form's header:
<form:form method="get" action="addContact" modelAttribute="contact">
Some further information about this error here
I already had this error before and the problem was that I didn't put a simple domain object like your "Contact" in tha Model, while my Spring form was waiting a domain object.
Try to do something like :
model.addAttribute("contact", new contact());
And that should work.
I need help. I am beginner in jsp, MVC. I want to validate form input with custom validator in Spring 3 MVC.
My validator class
package validators;
import models.UserModel;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
#Component
public class UserValidator implements Validator {
#Override
public boolean supports(Class clazz) {
return UserModel.class.isAssignableFrom(clazz);
}
#Override
public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstname", "Enter firstname.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "Enter surname.");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "login", "Enter login.");
}
}
Controller class
package controllers;
import java.util.ArrayList;
import models.UserModel;
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 validators.UserValidator;
import database.UserDB;
#Controller
public class UserController {
#RequestMapping(value="pouzivatel/new", method=RequestMethod.POST)
public ModelAndView newUser(#ModelAttribute UserModel user, BindingResult result){
UserValidator validator = new UserValidator();
validator.validate(user, result);
if(result.hasErrors()){
return new ModelAndView("/user/new","command",user);
}
...
}
Model for User
package models;
public class UserModel {
private String firstname="";
private String surname="";
public String getFirstname() {
return firstname;
}
public String getSurname() {
return surname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
JSP veiw new.jsp which is in directory /web-inf/user (it just only form)
<form:form method="post" action="new.html">
<fieldset>
<table>
<tr>
<td>
<form:label path="firstname">FirstName</form:label>
</td>
<td>
<form:input path="firstname" />
<form:errors path="firstname" />
</td>
</tr>
<tr>
<td>
<form:label path="surname">Surname</form:label>
</td>
<td>
<form:input path="surname" />
<form:errors path="surname" />
</td>
</tr>
</table>
</fieldset>
<div>
<button type="submit" id="btOk">Ok</button>
</div>
</form:form>
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="controllers" />
<context:component-scan base-package="validators" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Problem is a display validation message in view. Validation is successful and in variable resut (BindingResult) are errors. Controller return follow part of code
if(result.hasErrors()){
return new ModelAndView("/user/new","command",user);
Another way is use Annotation validation (I preffer custom validator), but why i can not see validation messages on view, when input fields are empty.
Can you give me example how to do it right?
Thanks for reply.
This happens because of mismatch between default model attribute names in view and controller:
When you write <form:form> without modelAttribute (or commandName) attribute, it uses default model attribute name command.
When you write #ModelAttribute UserModel user in your controller, it assumes that the name of this attribute is a decapitalized class name, i.e. userModel.
That is, error messages produced by validator are bound to model attribute named userModel, while your view tries to show errors for model attribute command.
You need to set a model attribute name explicitly, either in the view (<form:form modelAttribute = "userModel" ...>) or in the controller (#ModelAttribute("command")).