Struts2 visitor validation not work for JPA entity on EJB Module - maven

I am using the JPA entities as models for my web layer. I am including the EJB module as a dependency for my web project on pom.xml.
I have implemented an action called CreateUserAction which implements ModelDriven:
package actions.accounts;
import com.google.inject.Inject;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import facade.UserFacadeLocal;
import java.util.logging.Level;
import java.util.logging.Logger;
import models.User;
/**
*
* #author sergio
*/
public class CreateUserAction extends ActionSupport implements ModelDriven<User>{
#Inject
private UserFacadeLocal userFacade;
private User user = new User();
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String execute() throws Exception {
Logger.getLogger(SignupAction.class.getName()).log(Level.INFO, "Registrando usuario");
userFacade.create(user);
addActionMessage("Usuario registrado con éxito");
return SUCCESS;
}
#Override
public User getModel() {
return user;
}
}
user is an instance of the class models.User from EJB module:
package models;
import java.io.Serializable;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
#Entity(name = "USERS")
#NamedQueries({
#NamedQuery(name = "User.all", query = "SELECT u FROM USERS u"),
#NamedQuery(name = "User.find", query = "SELECT u FROM USERS u WHERE u.userName = :username")
})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "USER_NAME")
private String userName;
#Column(name = "PASSWD", length = 32,columnDefinition = "VARCHAR(32)")
private String password;
private String name;
private String lastname;
#Temporal(javax.persistence.TemporalType.DATE)
private Date birthday;
private String email;
private Integer mobile;
#ManyToMany(cascade={CascadeType.ALL})
#JoinTable(
name="USER_GROUPS",
joinColumns={ #JoinColumn(name="USER_NAME") },
inverseJoinColumns={ #JoinColumn(name="GROUP_NAME") }
)
private Set<Group> groups;
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 = hashPassword(password);
}
public Set<Group> getGroups() {
return groups;
}
public void setGroups(Set<Group> groups) {
this.groups = groups;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getMobile() {
return mobile;
}
public void setMobile(Integer mobile) {
this.mobile = mobile;
}
public String getFullname(){
return name + " " + lastname;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final User other = (User) obj;
if ((this.userName == null) ? (other.userName != null) :
!this.userName.equals(other.userName)) {
return false;
}
return true;
}
#Override
public int hashCode() {
int hash = 3;
hash = 83 * hash + (this.userName != null ? this.userName.hashCode() : 0);
return hash;
}
private String hashPassword(String password) {
String encoded = null;
try {
ByteBuffer passwdBuffer =
Charset.defaultCharset().encode(CharBuffer.wrap(password));
byte[] passwdBytes = passwdBuffer.array();
MessageDigest mdEnc = MessageDigest.getInstance("MD5");
mdEnc.update(passwdBytes, 0, password.length());
encoded = new BigInteger(1, mdEnc.digest()).toString(16);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
}
return encoded;
}
}
I want to use struts2 validation by the following configuration:
CreateUserAction-validation.xml into src/main/resources/actions/accounts
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<validator type="visitor">
<param name="fieldName">user</param>
<param name="appendPrefix">false</param>
<message />
</validator>
</validators>
User-validation.xml into src/main/resources/models
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN"
"http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
<field name="userName">
<field-validator type="required">
<message>You must enter a value for name.</message>
</field-validator>
</field>
<field name="name">
<field-validator type="required">
<message>You must enter a value for name.</message>
</field-validator>
</field>
</validators>
the User file is well placed?
and to finalize the action settings:
<action name="signup" class="actions.accounts.SignupAction">
<interceptor-ref name="store">
<param name="operationMode">RETRIEVE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result>/WEB-INF/views/accounts/signup.jsp</result>
</action>
<action name="create" class="actions.accounts.CreateUserAction">
<interceptor-ref name="store">
<param name="operationMode">STORE</param>
</interceptor-ref>
<interceptor-ref name="defaultStack" />
<result name="input" type="redirectAction">signup</result>
<result type="redirectAction">signup</result>
</action>
thanks in advance

Related

how i can resolve the error unable to insert NULL in ("NAWFEL". "ORDO_DEP_UUSATEUR". "EMPLOI")

I'm developing a user registration form, the problem I get is that when I want to test my web service in postman it shows me the following error in my eclipse console:
> 2020-06-02 19:50:04.559 WARN 1576 --- [nio-8484-exec-2]
> o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1400, SQLState:
> 23000 2020-06-02 19:50:04.560 ERROR 1576 --- [nio-8484-exec-2]
> o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-01400: impossible
> d'insérer NULL dans ("NAWFEL"."ORDO_DEP_UTILISATEUR"."EMPLOI")
>
> 2020-06-02 19:50:04.582 ERROR 1576 --- [nio-8484-exec-2]
> o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for
> servlet [dispatcherServlet] in context with path [] threw exception
> [Request processing failed; nested exception is
> org.springframework.dao.DataIntegrityViolationException: could not
> execute statement; SQL [n/a]; constraint [null]; nested exception is
> org.hibernate.exception.ConstraintViolationException: could not
> execute statement] with root cause
>
> oracle.jdbc.OracleDatabaseException: ORA-01400: impossible d'insérer
> NULL dans ("NAWFEL"."ORDO_DEP_UTILISATEUR"."EMPLOI")
>
> at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:513)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at
> oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:461)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at
> oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1104)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at
> oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:550)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at
> oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:268)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0] at
> oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:655)
> ~[ojdbc8-19.3.0.0.jar:19.3.0.0.0]
he tells me that I cannot insert a null value in the job "emploi" column, but I entered the value of the job column in my postman as you can see here:
this is my entity code :
package com.app.habilitation.entity;
import java.sql.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="ORDO_DEP_UTILISATEUR")
public class UserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="IDENTIFIANT")
private Integer IDENTIFIANT;
#ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(name="EMPLOI")
private EmploiEntity emploi;
#ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(name="ENTITE")
private EntiteEntity entite;
#Column(name="LOGIN")
private String login;
#Column(name="MOTDEPASSE")
private String mdp;
#Column(name="NOM")
private String nom;
#Column(name="PRENOM")
private String prenom;
#Column(name="CREEPAR")
private Integer creerpar;
#Column(name="ANNULEPAR")
private Integer annulepar;
#Column(name="STATUT")
private String statut;
#Column(name="DATEEFFET")
private Date dateeffet;
#Column(name="DATEFIN")
private Date datefin;
#Column(name="CREELE")
private Date creele;
#Column(name="MOTIFDEDESACTIVATION")
private String motifdedesactivation;
#Column(name="ANNULELE")
private Date annulele;
#Column(name="EMAIL")
private String email;
#Column(name="CONFIRMATIONMOTDEPASSE")
private String confirmation_mot_de_passe;
public String getConfirmation_mot_de_passe() {
return confirmation_mot_de_passe;
}
public void setConfirmation_mot_de_passe(String confirmation_mot_de_passe) {
this.confirmation_mot_de_passe = confirmation_mot_de_passe;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getIDENTIFIANT() {
return IDENTIFIANT;
}
public void setIDENTIFIANT(Integer iDENTIFIANT) {
IDENTIFIANT = iDENTIFIANT;
}
public EmploiEntity getEmploi() {
return emploi;
}
public void setEmploi(EmploiEntity emploi) {
this.emploi = emploi;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getMdp() {
return mdp;
}
public void setMdp(String mdp) {
this.mdp = mdp;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public Integer getCreerpar() {
return creerpar;
}
public void setCreerpar(Integer creerpar) {
this.creerpar = creerpar;
}
public Integer getAnnulepar() {
return annulepar;
}
public void setAnnulepar(Integer annulepar) {
this.annulepar = annulepar;
}
public String getStatut() {
return statut;
}
public void setStatut(String statut) {
this.statut = statut;
}
public Date getDateeffet() {
return dateeffet;
}
public void setDateeffet(Date dateeffet) {
this.dateeffet = dateeffet;
}
public Date getDatefin() {
return datefin;
}
public void setDatefin(Date datefin) {
this.datefin = datefin;
}
public Date getCreele() {
return creele;
}
public void setCreele(Date creele) {
this.creele = creele;
}
public String getMotifdedesactivation() {
return motifdedesactivation;
}
public void setMotifdedesactivation(String motifdedesactivation) {
this.motifdedesactivation = motifdedesactivation;
}
public Date getAnnulele() {
return annulele;
}
public void setAnnulele(Date annulele) {
this.annulele = annulele;
}
public EntiteEntity getEntite() {
return entite;
}
public void setEntite(EntiteEntity entite) {
this.entite = entite;
}
public UserEntity(EmploiEntity emploi, EntiteEntity entite, String login, String mdp, String nom, String prenom,
Integer creerpar, Integer annulepar, String statut, Date dateeffet, Date datefin, Date creele,
String motifdedesactivation, Date annulele, String email, String confirmation_mot_de_passe) {
this.emploi = emploi;
this.entite = entite;
this.login = login;
this.mdp = mdp;
this.nom = nom;
this.prenom = prenom;
this.creerpar = creerpar;
this.annulepar = annulepar;
this.statut = statut;
this.dateeffet = dateeffet;
this.datefin = datefin;
this.creele = creele;
this.motifdedesactivation = motifdedesactivation;
this.annulele = annulele;
this.email = email;
this.confirmation_mot_de_passe = confirmation_mot_de_passe;
}
public UserEntity() {
}
#Override
public String toString() {
return "UserEntity [IDENTIFIANT=" + IDENTIFIANT + ", emploi=" + emploi + ", entite=" + entite + ", login="
+ login + ", mdp=" + mdp + ", nom=" + nom + ", prenom=" + prenom + ", creerpar=" + creerpar
+ ", annulepar=" + annulepar + ", statut=" + statut + ", dateeffet=" + dateeffet + ", datefin="
+ datefin + ", creele=" + creele + ", motifdedesactivation=" + motifdedesactivation + ", annulele="
+ annulele + ", email=" + email + ", confirmation_mot_de_passe=" + confirmation_mot_de_passe + "]";
}
}
and this is my dao ( i use jpa) :
package com.app.habilitation.dao;
import org.springframework.data.jpa.repository.JpaRepository;
import com.app.habilitation.entity.UserEntity;
public interface UserDao extends JpaRepository<UserEntity, Integer> {
}
and this is my userService :
package com.app.habilitation.service;
import java.util.List;
import com.app.habilitation.entity.UserEntity;
public interface UserService {
public void save (UserEntity theUser);
}
and this is my userServiceImpl :
package com.app.habilitation.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.app.habilitation.dao.UserDao;
import com.app.habilitation.entity.UserEntity;
#Service
public class UserServiceImpl implements UserService {
private UserDao userDao;
#Autowired
public UserServiceImpl (UserDao theuserDao) {
userDao = theuserDao;
}
#Override
#Transactional
public void save(UserEntity theUser) {
userDao.save(theUser);
}
}
and this is my controller :
package com.app.habilitation.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.app.habilitation.entity.UserEntity;
import com.app.habilitation.service.UserService;
#SpringBootApplication
#RestController
#CrossOrigin(origins = "*")
//#RequestMapping("/user")
public class UserController {
private UserService userService;
#Autowired
public UserController (UserService theuserService) {
userService=theuserService;
}
#GetMapping("/")
public String login() {
return "authenticaated succesfully";
}
#GetMapping("/getUsers")
public String getUsers() {
return "users";
}
#PostMapping("/addUser")
public UserEntity addUser (#RequestBody UserEntity theUser) {
System.out.println("test");
userService.save(theUser);
return theUser;
}
}
and this is my table user (i use oracle 10g) :
can someone help me please ?
Check your Column definition, is it a Many to one or just a regular column?
#Column(name="EMPLOI")
private EmploiEntity emploi;
if it is your Emploi created right?

form:select does not set the selected value

Basically I need a CRUD application for payments. Each payment is assigned to one account.
My jsp page shows the correct list of "account" objects but it does not set the selected account.
Question: How can I achieve a dropdown box with the assigned account pre-selected?
Question: The assignment (account to payment) works, but only with the below code in my PaymentDaoImpl.java (marked as workaround). Why is this the case?
PaymentDaoImpl.java
..
#Override
#Transactional
public int insertRow(Payment obj) {
// Session session = HibernateUtil.getSessionFactory().openSession();
Session session = sessionFactory.openSession();
// !!!! workaround?? If I don't do this, account won't be assigned
int accountId = obj.getAccount().getId();
Account account = (Account) session.get(Account.class, accountId);
obj.setAccount(account);
Transaction tx = session.beginTransaction();
session.saveOrUpdate(obj);
tx.commit();
Serializable id = session.getIdentifier(obj);
session.close();
return (Integer) id;
}
..
jsp:
<form:select path="account.id" >
<form:option value="-1" label="Select Account" />
<form:options items="${accountList}" itemValue="id" itemLabel="iban" />
</form:select>
Domain Account.java:
package com.beingjavaguys.domain;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.*;
import org.springframework.beans.factory.annotation.Autowired;
#Entity
public class Account {
#Id
#GeneratedValue
private int id;
private String iban;
private String bank;
private String beschreibung;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIban() {
return iban;
}
public void setIban(String iban) {
this.iban = iban;
}
public String getBank() {
return bank;
}
public void setBank(String bank) {
this.bank = bank;
}
public String getBeschreibung() {
return beschreibung;
}
public void setBeschreibung(String beschreibung) {
this.beschreibung = beschreibung;
}
}
Domain Payment
package com.beingjavaguys.domain;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import org.springframework.beans.factory.annotation.Autowired;
#Entity
public class Payment {
private int id;
private Account account;
private float amount;
private String text;
private String comment;
#Id
#GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#ManyToOne(cascade = CascadeType.ALL, targetEntity = Account.class, fetch=FetchType.EAGER)
#JoinColumn(name="fk_account")
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public float getAmount() {
return amount;
}
public void setAmount(float amount) {
this.amount = amount;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
}
PaymentController.java
package com.beingjavaguys.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.beingjavaguys.domain.Payment;
import com.beingjavaguys.services.AccountService;
import com.beingjavaguys.services.PaymentService;
#Controller
#RequestMapping("/payment")
public class PaymentController {
#Autowired
PaymentService dataService;
#Autowired
AccountService accountService;
#RequestMapping("form")
public ModelAndView getForm(#ModelAttribute Payment obj) {
ModelAndView mav = new ModelAndView("payment/form");
mav.addObject("accountList", accountService.getList());
return mav;
}
#RequestMapping("insert")
public ModelAndView insert(#ModelAttribute Payment obj) {
dataService.insertRow(obj);
return new ModelAndView("redirect:list");
}
#RequestMapping("list")
public ModelAndView getList() {
List objList = dataService.getList();
return new ModelAndView("payment/list","objList",objList);
}
#RequestMapping("delete")
public ModelAndView deleteUser(#RequestParam int id) {
dataService.deleteRow(id);
return new ModelAndView("redirect:list");
}
#RequestMapping("edit")
public ModelAndView editUser(#RequestParam int id,#ModelAttribute Payment obj) {
ModelAndView mav = new ModelAndView("payment/form");
Payment paymentObj = dataService.getRowById(id);
mav.addObject("accountList", accountService.getList());
mav.addObject("paymentObj", paymentObj);
return mav;
}
#RequestMapping("update")
public ModelAndView updateUser(#ModelAttribute Payment obj) {
dataService.updateRow(obj);
return new ModelAndView("redirect:list");
}
}
Can you have a look on my implementation of the AccountEditor? I need the AccountService to lookup the account, or not? However, I don't get the service instantiated here..
public class AccountEditor extends PropertyEditorSupport {
#Autowired
AccountService dataService; // == null ??
#Override
public void setAsText(String text) {
Account account = lookupAccount(text); // lookup account by accountId
// text
setValue(account);
}
private Account lookupAccount(String text) {
int id = Integer.parseInt(text);
return dataService.getRowById(id);
}
}
What you need is a PropertyEditor implementation to convert from a String accountId to an Account object. Then in your jsp you use the path form:select path="account" instead of form:select path="account.id"
Implement a PropertyEditor as follows
public class AccountEditor extends PropertyEditorSupport{
#Override
public void setAsText(String text){
Account account = lookupAccount(text); //lookup account by accountId text
setValue(account);
}
}
Then register your AccountEditor in your controller
#InitBinder
public void initBinder(WebDataBinder binder){
binder.registerCustomEditor(Account.class , new AccountEditor());
}
With the above changes you wont need your workaround. Your solution is only setting the id property of the account and not the whole object

Facing difficulty with Hibernate HQL when applying it to H2

I am new to hibernate and spring maven environment.
I have tried implementing an embedded db using H2, which earlier used MySQL. there are two DAO's
OffersDao.java
package com.skam940.main.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Component("offersDao")
#Transactional
public class OffersDao {
#Autowired
private SessionFactory sessionFactory;
public Session session() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
public List<Offer> getOffers() {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u").add(Restrictions.eq("u.enabled", true));
return crit.list();
}
#SuppressWarnings("unchecked")
public List<Offer> getOffers(String username) {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u");
crit.add(Restrictions.eq("u.enabled", true));
crit.add(Restrictions.eq("u.username", username));
return crit.list();
}
public void saveOrUpdate(Offer offer) {
session().saveOrUpdate(offer);
}
public boolean delete(int id) {
Query query = session().createQuery("delete from Offer where id=:id");
query.setLong("id", id);
return query.executeUpdate() == 1;
}
public Offer getOffer(int id) {
Criteria crit = session().createCriteria(Offer.class);
crit.createAlias("user", "u");
crit.add(Restrictions.eq("u.enabled", true));
crit.add(Restrictions.idEq(id));
return (Offer) crit.uniqueResult();
}
}
and UsersDao.java
package com.skam940.main.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional
#Component("usersDao")
public class UsersDao {
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private SessionFactory sessionFactory;
public Session session() {
return sessionFactory.getCurrentSession();
}
#Transactional
public void create(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
session().save(user);
}
public boolean exists(String username) {
Criteria crit = session().createCriteria(User.class);
crit.add(Restrictions.idEq(username));
User user = (User) crit.uniqueResult();
return user != null;
}
#SuppressWarnings("unchecked")
public List<User> getAllUsers() {
return session().createQuery("from User").list();
}
}
no the thing is I get an exception of
HTTP Status 500 - PreparedStatementCallback; bad SQL grammar [select username, password, enabled from users where binary username = ?]; nested exception is org.h2.jdbc.JdbcSQLException: Column "BINARY" not found; SQL statement:
And the thing I want to do here to make the username case sensitive, and apparently H2 recognises BINARY as a table name but not as a type or what ever you call that, can any one tell which which method is implementing this SQL grammar?
User.java
package com.skam940.main.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotBlank;
import com.skam940.main.validation.ValidEmail;
#Entity
#Table(name="users")
public class User {
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=6, max=15, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Pattern(regexp="^\\w{8,}$", groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Id
#Column(name="username")
private String username;
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Pattern(regexp="^\\S+$", groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=8, max=15, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
private String password;
#ValidEmail(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
private String email;
#NotBlank(groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Size(min=3, max=30, groups={FormValidationGroup.class})
private String name;
private boolean enabled = false;
private String authority;
public User() {
}
public User(String username, String name, String password, String email, boolean enabled,
String authority) {
this.username = username;
this.name = name;
this.password = password;
this.email = email;
this.enabled = enabled;
this.authority = authority;
}
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 boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((authority == null) ? 0 : authority.hashCode());
result = prime * result + ((email == null) ? 0 : email.hashCode());
result = prime * result + (enabled ? 1231 : 1237);
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result
+ ((username == null) ? 0 : username.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (authority == null) {
if (other.authority != null)
return false;
} else if (!authority.equals(other.authority))
return false;
if (email == null) {
if (other.email != null)
return false;
} else if (!email.equals(other.email))
return false;
if (enabled != other.enabled)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
#Override
public String toString() {
return "User [username=" + username + ", email=" + email + ", name="
+ name + ", enabled=" + enabled + ", authority=" + authority
+ "]";
}
}
Offer.java
package com.skam940.main.dao;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
#Entity
#Table(name="offers")
public class Offer {
#Id
#GeneratedValue
// because this is an auto increment value
private int id;
#Size(min=5, max=255, groups={PersistenceValidationGroup.class, FormValidationGroup.class})
#Column(name="text")
private String text;
// every user can have only one offer
#ManyToOne
#JoinColumn(name="username")
private User user;
public Offer() {
this.user = new User();
}
public Offer(User user, String text) {
this.user = user;
this.text = text;
}
public Offer(int id, User user, String text) {
this.id = id;
this.user = user;
this.text = text;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getUsername() {
return user.getUsername();
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((text == null) ? 0 : text.hashCode());
result = prime * result + ((user == null) ? 0 : user.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Offer other = (Offer) obj;
if (text == null) {
if (other.text != null)
return false;
} else if (!text.equals(other.text))
return false;
if (user == null) {
if (other.user != null)
return false;
} else if (!user.equals(other.user))
return false;
return true;
}
#Override
public String toString() {
return "Offer [id=" + id + ", text=" + text + ", user=" + user + "]";
}
}
the full file content is available here -> https://app.box.com/s/c3uq71khbwf05p8asu27
This query is coming from your Spring security configuration, please check security-context.xml, you can find Spring security authentication provider that uses authorities-by-username-query as
select username, authority from users where binary username = ?
This query uses MySQL-specific function BINARY for case-sensitive comparison (http://gilfster.blogspot.com/2005/08/case-sensitivity-in-mysql.html). H2, on the other hand, is case sensitive by default.
Try to change it with
select username, authority from users where username = ?
The same applies to users-by-username-query property.

Spring MVC - Hibernate mapped object partially filled when using POST request method

Since I've decided to use same JSP for adding and editing posts, I just pass an attribute "saveUrl" which defines the action for my form in the JSP. Adding a new post works fine, but when editing a post, the object returned to the controller is missing all attributes except for the description.
What am I missing or doing wrong here?
Thanks for help!
My controller:
#Controller
public class BlogController {
private static final Logger logger = LoggerFactory.getLogger(BlogController.class);
#Autowired
private BlogPostManager bpManager;
#Autowired
private UserManager usrManager;
.....
#RequestMapping(value = "addPost", method = RequestMethod.GET)
public String addPost(Locale locale, Model model, Principal principal) {
model.addAttribute("post", new BlogPostEntity());
/** some more code here **/
return "addEditPost";
}
#RequestMapping(value = "addPostProcess", method = RequestMethod.POST)
public String addPostProcess(Locale locale, Model model, Principal principal, #ModelAttribute("post") BlogPostEntity blogPost) {
blogPost.setDate(new Date());
blogPost.setAuthor(usrManager.getUser(principal.getName()));
bpManager.addBlogPost(blogPost);
return "redirect:/latest";
}
#RequestMapping(value = "editPost/{id}", method = RequestMethod.GET)
public String editPost(Locale locale, Model model, Principal principal, #PathVariable Integer id) {
model.addAttribute("post", bpManager.getBlogPost(id));
model.addAttribute("username", getUsername(principal));
model.addAttribute("saveUrl", "");
return "addEditPost";
}
#RequestMapping(value = "editPost/{id}", method = RequestMethod.POST)
public String editPostProcess(Locale locale, Model model, Principal principal, #ModelAttribute("post") BlogPostEntity blogPost) {
bpManager.updateBlogPost(blogPost);
return "redirect:/latest";
}
/** some private methods **/
}
addEditPost.jsp
NOTE: this jsp is acting as a body of Apache tiles.
<h2>Create new post:</h2>
<form:form modelAttribute="post" action="${saveUrl}" method='POST'>
<table>
<tr>
<td><form:label path="title">Title:</form:label></td>
<td><form:input path="title"></form:input></td>
</tr>
<tr>
<td><form:label path="description">Description:</form:label></td>
<td><form:input path="description"></form:input></td>
</tr>
<tr>
<td><form:label path="text">Text:</form:label></td>
<td><form:input path="text"></form:input></td>
</tr>
<tr>
<td><input value="Save" type="submit"></td>
<td></td>
</tr>
</table>
</form:form>
The mapped BlogPost class:
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "BLOGPOST")
public class BlogPostEntity {
#Id
#GeneratedValue
#Column(name = "ID")
private int id;
#Column(name = "TITLE", nullable = false, length = 100)
private String title;
#Column(name = "DESCRIPTION", length = 500)
private String description;
#Column(name = "TEXT", length = 5000)
private String text;
#Column(name = "DATE")
private Date date;
#ManyToOne(targetEntity = UserEntity.class)
#JoinColumn(name = "authorid", referencedColumnName = "id")
private UserEntity author;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getId() {
return id;
}
public void setAuthor(UserEntity author) {
this.author = author;
}
public UserEntity getAuthor() {
return author;
}
}
DAO for blogpost:
import java.util.ArrayList;
import java.util.List;
import org.danizmax.simpleblog.entity.BlogPostEntity;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
#Repository("blogpostdao")
public class BlogPostDaoImpl implements BlogPostDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void addBlogPost(BlogPostEntity blogPost) {
getSession().persist(blogPost);
}
#Override
public void removeBlogPost(int id) {
BlogPostEntity entity = (BlogPostEntity) sessionFactory.getCurrentSession().load(BlogPostEntity.class, id);
if (entity != null) {
getSession().delete(entity);
}
}
#Override
#SuppressWarnings("unchecked")
public List<BlogPostEntity> latest() {
List<BlogPostEntity> result = new ArrayList<BlogPostEntity>();
try {
result = getSession().createQuery("FROM BlogPostEntity ORDER BY 'id' desc LIMIT 5;").list();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
#SuppressWarnings("unchecked")
public List<BlogPostEntity> listPosts(int userId) {
List<BlogPostEntity> result = new ArrayList<BlogPostEntity>();
try {
result = getSession().createQuery("FROM UserEntity").list();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
public void updateBlogPost(BlogPostEntity blogPost) {
blogPost = getBlogPost(blogPost.getId());
getSession().update(blogPost);
}
#Override
public BlogPostEntity getBlogPost(int id) {
return (BlogPostEntity) getSession().get(BlogPostEntity.class, id);
}
private Session getSession() {
return sessionFactory.getCurrentSession();
}
}
UPDATE: I've been experimenting a bit and tried method from HERE, but the object returned to the controler was still empty.
Then I changed the saveURL in JSP to (I read it might be important HERE):
<c:url var="addUrl" value="/secure/postProcess"/>
<form:form modelAttribute="post" action="${addUrl}" method='POST'>
and now the object is filled, only the id is still empty. So there is something probably wrong with the JSP.

Apache cxf basic authentication

I have a running example of apache cxf but when I run this wsdl file provided by my code is not authenticated I don't know how to pass the username and password to soapui
The code is:
ORDER.JAVA
package demo.order;
public class Order {
private String customerID;
private String itemID;
private int qty;
private double price;
// Constructor
public Order() {
}
public String getCustomerID() {
return customerID;
}
public void setCustomerID(String customerID) {
this.customerID = customerID;
}
public String getItemID() {
return itemID;
}
public void setItemID(String itemID) {
this.itemID = itemID;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package demo.order;
import javax.jws.WebService;
#WebService
public interface OrderProcess {
String processOrder(Order order);
}
package demo.order;
import javax.jws.WebService;
#org.apache.cxf.interceptor.InInterceptors (interceptors = {"demo.order.server.OrderProcessUserCredentialInterceptor" })
#WebService
public class OrderProcessImpl implements OrderProcess {
public String processOrder(Order order) {
System.out.println("Processing order...");
String orderID = validate(order);
return orderID;
}
/**
* Validates the order and returns the order ID
**/
private String validate(Order order) {
String custID = order.getCustomerID();
String itemID = order.getItemID();
int qty = order.getQty();
double price = order.getPrice();
if (custID != null && itemID != null && qty > 0 && price > 0.0) {
return "ORD1234";
}
return null;
}
}
_______________
package demo.order.client;
import demo.order.OrderProcess;
import demo.order.Order;
import org.apache.cxf.frontend.ClientProxy;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public final class Client {
public Client() {
}
public static void main(String args[]) throws Exception {
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext(new String[] {"demo/order/client/client-beans.xml"});
OrderProcess client = (OrderProcess) context.getBean("orderClient");
OrderProcessClientHandler clientInterceptor = new OrderProcessClientHandler();
clientInterceptor.setUserName("John");
clientInterceptor.setPassword("password");
org.apache.cxf.endpoint.Client cxfClient = ClientProxy.getClient(client);
cxfClient.getOutInterceptors().add(clientInterceptor);
Order order = new Order();
order.setCustomerID("C001");
order.setItemID("I001");
order.setQty(100);
order.setPrice(200.00);
String orderID = client.processOrder(order);
String message = (orderID == null) ? "Order not approved" : "Order approved; order ID is " + orderID;
System.out.println(message);
}
}
_____________________
package demo.order.client;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class OrderProcessClientHandler extends AbstractSoapInterceptor {
public String userName;
public String password;
public OrderProcessClientHandler() {
super(Phase.WRITE);
addAfter(SoapPreProtocolOutInterceptor.class.getName());
}
public void handleMessage(SoapMessage message) throws Fault {
System.out.println("OrderProcessClientHandler handleMessage invoked");
DocumentBuilder builder = null;
try {
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
Document doc = builder.newDocument();
Element elementCredentials = doc.createElement("OrderCredentials");
Element elementUser = doc.createElement("username");
elementUser.setTextContent(getUserName());
Element elementPassword = doc.createElement("password");
elementPassword.setTextContent(getPassword());
elementCredentials.appendChild(elementUser);
elementCredentials.appendChild(elementPassword);
// Create Header object
QName qnameCredentials = new QName("OrderCredentials");
Header header = new Header(qnameCredentials, elementCredentials);
message.getHeaders().add(header);
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
_________________________
CLIENTBEAN.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="orderClient" serviceClass="demo.order.OrderProcess" address="http://localhost:8080/OrderProcess" />
</beans>
_______________________
package demo.order.server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import demo.order.OrderProcess;
import demo.order.OrderProcessImpl;
public class OrderProcessServerStart {
public static void main(String[] args) throws Exception {
OrderProcess orderProcess = new OrderProcessImpl();
JaxWsServerFactoryBean server = new JaxWsServerFactoryBean();
server.setServiceBean(orderProcess);
server.setAddress("http://localhost:8787/OrderProcess");
server.create();
System.out.println("Server ready....");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
___________________________
package demo.order.server;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class OrderProcessUserCredentialInterceptor extends AbstractSoapInterceptor {
private String userName;
private String password;
public OrderProcessUserCredentialInterceptor() {
super(Phase.PRE_INVOKE);
}
public void handleMessage(SoapMessage message) throws Fault {
System.out.println("OrderProcessUserCredentialInterceptor handleMessage invoked");
QName qnameCredentials = new QName("OrderCredentials");
// Get header based on QNAME
if (message.hasHeader(qnameCredentials )) {
Header header = message.getHeader(qnameCredentials);
Element elementOrderCredential= (Element) header.getObject();
Node nodeUser = elementOrderCredential.getFirstChild();
Node nodePassword = elementOrderCredential.getLastChild();
if (nodeUser != null) {
userName = nodeUser.getTextContent();
}
if (nodePassword != null) {
password = nodePassword.getTextContent();
}
}
System.out.println("userName retrieved from SOAP Header is " + userName);
System.out.println("password retrieved from SOAP Header is " + password);
// Perform dummy validation for John
if ("John".equalsIgnoreCase(userName) && "password".equalsIgnoreCase(password)) {
System.out.println("Authentication successful for John");
} else {
throw new RuntimeException("Invalid user or password");
}
}
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;
}
}
_______________
I have these files and the program compile succesfully and creting the wsdl file
but its not working on soapui means username and password are null when requsting through soapui,
please suggest me how to overcome this problem of basic authentication
and how to pass the usename and password to soap ui
For Basic authentication in SOAP UI, navigate to your Request, single click on it will display a panel in the left bottom corner. Your config for BASIC Authentication should be something like this:
Add your username and password to the appropriate fields.
For your client I see you are using Spring. So jaxws:client provides username and password attributes for authentication. You can add them like this:
<jaxws:client id="orderClient"
serviceClass="demo.order.OrderProcess"
address="http://localhost:8080/OrderProcess"
username="yourUsername"
password="yourPassword"/>

Resources