私はspring4.2.3およびhibernate5.1.0ベースのプロジェクトでフォーム検証にカスタムアノテーションを使用しています。カスタムアノテーションを使用したスプリングフォーム検証
1)私の注釈インターフェイスは私のロジッククラスUnitConstraintValidator私はカスタムアノテーションを使用していますどここの
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.rapidtech.rapidtechorganic.custom.annotation.IsUnit;
public class UnitConstraintValidator implements ConstraintValidator<IsUnit, String> {
@Override
public void initialize(IsUnit unit) {
// TODO Auto-generated method stub
}
@Override
public boolean isValid(String unit, ConstraintValidatorContext cxt) {
if(unit.equals(null) || unit == null){
return false;
}
if(unit.matches("kg|KG|Kg|Litre|litre|lt|ton|Ton")){
return true;
}
return false;
}
}
3)マイ・モデル・クラスのように見えます)この
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import com.rapidtech.rapidtechorganic.custom.logic.UnitConstraintValidator;
@Documented
@Constraint(validatedBy = UnitConstraintValidator.class)
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IsUnit {
String message() default "Please Enter a valid UNIT e.g. kg,litre,ton";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2のように見えます
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.rapidtech.rapidtechorganic.custom.annotation.IsUnit;
@JsonIgnoreProperties(ignoreUnknown = true)
@Entity
public class Lot implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long lotId;
@Size(min=5,max=30)
private String lotNumber;
@IsUnit
private String lotName;
@OneToOne(cascade = {CascadeType.ALL})
private ProductAvailable productAvailable;
public long getLotId() {
return lotId;
}
public void setLotId(long lotId) {
this.lotId = lotId;
}
public String getLotNumber() {
return lotNumber;
}
public void setLotNumber(String lotNumber) {
this.lotNumber = lotNumber;
}
public String getLotName() {
return lotName;
}
public void setLotName(String lotName) {
this.lotName = lotName;
}
public ProductAvailable getProductAvailable() {
return productAvailable;
}
public void setProductAvailable(ProductAvailable productAvailable) {
this.productAvailable = productAvailable;
}
}
4)カスタム注釈を使用しているMy ProductAvailableモデルクラス
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.validation.constraints.Size;
import com.rapidtech.rapidtechorganic.custom.annotation.IsUnit;
@Entity
public class ProductAvailable implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long productAvailableId;
@Size(min=2,max=30,message="ahha ahha ahha")
private String productAvailableName;
@IsUnit
private String productAvailableUnit;
private double productAvailableUnitTransportationCharge;
private double productAvailableUnitLabourCharge;
private double productAvailableUnitOtherCharge;
private long productAvailableQuantity;
private double productAvailableUnitPrice;
@OneToOne
private Lot lot;
public long getProductAvailableId() {
return productAvailableId;
}
public void setProductAvailableId(long productAvailableId) {
this.productAvailableId = productAvailableId;
}
public String getProductAvailableName() {
return productAvailableName;
}
public void setProductAvailableName(String productAvailableName) {
this.productAvailableName = productAvailableName;
}
public long getProductAvailableQuantity() {
return productAvailableQuantity;
}
public void setProductAvailableQuantity(long productAvailableQuantity) {
this.productAvailableQuantity = productAvailableQuantity;
}
public double getProductAvailableUnitPrice() {
return productAvailableUnitPrice;
}
public void setProductAvailableUnitPrice(double productAvailableUnitPrice) {
this.productAvailableUnitPrice = productAvailableUnitPrice;
}
public String getProductAvailableUnit() {
return productAvailableUnit;
}
public void setProductAvailableUnit(String productAvailableUnit) {
this.productAvailableUnit = productAvailableUnit;
}
public double getProductAvailableUnitTransportationCharge() {
return productAvailableUnitTransportationCharge;
}
public void setProductAvailableUnitTransportationCharge(double productAvailableUnitTransportationCharge) {
this.productAvailableUnitTransportationCharge = productAvailableUnitTransportationCharge;
}
public double getProductAvailableUnitLabourCharge() {
return productAvailableUnitLabourCharge;
}
public void setProductAvailableUnitLabourCharge(double productAvailableUnitLabourCharge) {
this.productAvailableUnitLabourCharge = productAvailableUnitLabourCharge;
}
public double getProductAvailableUnitOtherCharge() {
return productAvailableUnitOtherCharge;
}
public void setProductAvailableUnitOtherCharge(double productAvailableUnitOtherCharge) {
this.productAvailableUnitOtherCharge = productAvailableUnitOtherCharge;
}
public Lot getLot() {
return lot;
}
public void setLot(Lot lot) {
this.lot = lot;
}
}
私は検証のためにhibernate-validator4.1.0.FinalとJSR 303を使用しています。
私は2つのモデルクラスLotとProductAvailableをマッピングOneToManyで持っているので、1つのLotは多くのProductAvailableを持つことができます。
私の問題は、次のとおりです。私のカスタムannotaionクラスロットと細かい作業が、クラスProductAvailableの場合に例外をスローするIsUnit。
例外は次のとおりです。
javax.validation.ConstraintViolationException: Validation failed for classes [com.rapidtech.rapidtechorganic.model.ProductAvailable] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='Please Enter a valid UNIT e.g. kg,litre,ton', propertyPath=productAvailableUnit, rootBeanClass=class com.rapidtech.rapidtechorganic.model.ProductAvailable, messageTemplate='Please Enter a valid UNIT e.g. kg,litre,ton'}
]
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1295)
org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:468)
org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3135)
org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2352)
org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485)
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147)
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38)
org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231)
org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65)
com.rapidtech.rapidtechorganic.dao.AbstractDao.save(AbstractDao.java:30)
com.rapidtech.rapidtechorganic.dao.lot.LotDaoImpl.save(LotDaoImpl.java:22)
com.rapidtech.rapidtechorganic.service.LotServiceImpl.save(LotServiceImpl.java:25)
com.rapidtech.rapidtechorganic.controller.LotController.saveLotController(LotController.java:59)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
私のコントローラクラスは次のようになります。
@RequestMapping(value = "/saveLot", method = RequestMethod.POST)
public ModelAndView saveLotController(@Valid @ModelAttribute(value="lot") Lot lot, BindingResult result) {
ModelAndView model;
if(result.hasErrors()){
model = new ModelAndView("saveLotForm");
}
else {
Services lotService = (LotServiceImpl) appContext.getBean("lotServiceImpl");
lot.getProductAvailable().setLot(lot);
lotService.save(lot);
model = new ModelAndView("Success");
model.addObject("successMessage","Lot "+lot.getLotName()+" Saved Successfully!");
}
return model;
}
すべてのヘルプはappreaciatedと事前に感謝されるだろう。
それに問題がありますか?これは検証し、検証規則に準拠していません。そう、はいそれは失敗するでしょう。 –
正確にどこに教えていただけますか? – tinku