Ta vyjimka se vyhodi v pripade, ze ten objekt neprojde validaci a dela
to volani binder.closeNoCatch();. Muze se to samozrejme ostranit.
Problem je v tom, ze MultiActionController neregistruje ty errors, takze
to je zaregistrujte manualne viz dale.
public class ExtendedMultiActionController extends MultiActionController {
protected void bind(ServletRequest request, Object command) throws
Exception{
ServletRequestDataBinder binder = createBinder(request, command);
Validator validators[] = getValidators();
binder.bind(request);
if (validators != null) {
for (int i = 0; i < validators.length; i++) {
if (validators[i].supports(command.getClass()))
ValidationUtils.invokeValidator(validators[i], command,
binder.getErrors());
}
}
onBindAndValidate((HttpServletRequest)request, command,
binder.getErrors());
}
protected void onBindAndValidate(HttpServletRequest request,
Object command, BindException errors) throws Exception {
// empty default implementation
}
}
public class TestMultiActionController extends
ExtendedMultiActionController {
public ModelAndView save(HttpServletRequest req,
HttpServletResponse resp, Object command) {
return new ModelAndView("multiactiontest", "action", "save");
}
public ModelAndView update(HttpServletRequest req,
HttpServletResponse resp, Object command) {
return new ModelAndView("multiactiontest", "action", "update");
}
/**
* @see
cz.sweb.pichlik.springtutorial.captcha.ExtendedMultiActionController#onBindAndValidate(javax.servlet.http.HttpServletRequest,
java.lang.Object, org.springframework.validation.BindException)
*/
@Override
protected void onBindAndValidate(HttpServletRequest request, Object
command, BindException errors) throws Exception {
String objectName = "Foo";
String[] codes = {"Foo"};
Object[] arguments = {};
String defaultMessage = "Something went wrong!";
ObjectError oe = new ObjectError(objectName, codes, arguments,
defaultMessage);
errors.addError(oe);
request.setAttribute("errorMessages", errors.getAllErrors());
}
}
<html>
<head>
<title>Action</title>
</head>
<body>
<c:out value="${action}" />
<ul>
<c:forEach items="${errorMessages}"
var="errorMessage">
<li style="color:red"><c:out
value="${errorMessage.defaultMessage}"/></li>
</font>
</c:forEach>
</ul>
</body>
</html>
Cele si mi to ovsem nelibi, IMHO bych chtel ten jejich
MultiActionController a nebo si napsat vlastni...
Burdik Petr napsal(a):
Posunul jsem se o kousek dal v te vlastni validaci pomoci toho
ExtendedMultiActionControlleru:
org.springframework.web.bind.ServletRequestBindingException: Errors
binding onto object 'command' at
org.springframework.web.bind.ServletRequestDataBinder.closeNoCatch(ServletRequestDataBinder.java:145)
at
net.itbridge.itsynapse2.web.controllers.ItsynapseMAC.bind(ItsynapseMAC.java:62)
Ve formulari jsem dal toto:
<spring:hasBindErrors name="command">
<div class="form-form" style="text-align: right;">
<b>Please fix all errors!</b>
${errors.errorCount}
</div>
</spring:hasBindErrors>
To nevypise nic.
Pekny vecer. Pokud by nekoho neco napadlo, budu moc rad.
Pet
Burdik Petr napsal(a):
Zkousel jsem ted klasickou validaci. Chodi Vam nekomu
multiactioncontroller s validatorem dohromady?
Extended controller jsem zkousel. Narazil jsem uz u validators. Ty
jsou totiz definovany ve tride MultiActionController jako private. To
by jeste nevadilo. Pouzil jsem getValidators(). Ale stejne se mi
nedarilo bindovat to s temi vlastnimi validacnimi pravidly. I kdyz
presne rozumim tomu, jak jste to chtel.
V logu a nikde zadna chyba, ale stejne to nefunguje. A to mam v tom
validatoru vzdy vyvolanou chybu.
Pet
Roman Pichlík napsal(a):
Nerozumim, pokud bude jeden multiactioncontroller pro CRUD operace
jedne beany, pak vam staci jeden validator.
Pokud potrebujete udelat custom validaci, tak bych prekryl metodu
bind a udelal to podobne jako to maji fomr controllery.
public class ExtendedMultiActionController extends
MultiActionController{
protected void bind(ServletRequest request, Object command) {
ServletRequestDataBinder binder = createBinder(request, command);
binder.bind(request);
if (this.validators != null) {
for (int i = 0; i < this.validators.length; i++) {
if (this.validators[i].supports(command.getClass()))
ValidationUtils.invokeValidator(this.validators[i], command,
binder.getErrors());
}
}
onBindAndValidate(request, command, binder.getErrors())
binder.closeNoCatch();
}
protected void onBindAndValidate(HttpServletRequest request, Object
command, BindException errors) throws Exception{
//empty default implementation
}
}
potomek si pak v onBindAndValidate implementuje custom validaci bez
validatoru :-).
Je to alespon trochu srozumitlene?
Burdik Petr napsal(a):
Ok,
to vim. Ale problem je ze pokud to budu pouzivat beznym zpusobem,
budu potrebovat nekolik validatoru pro ten multiactioncontroller.
Krom toho takto bych to mohl standardni cestou vratit i pokud treba
dany objekt uz existuje. Tedy si "pridat" chybu az v controlleru.
Proste vetsi kontrola nad tim co se deje.
Pri snaze ziskat RequestContext a z nej kolekci Errors jsem ale
narazil. Nedari se mi prijit na to jak ji ziskat. Toto je spatne.
import org.springframework.web.servlet.support.RequestContext;
RequestContext rc = new RequestContext(request);
Nevim co dat jako parametr
Errors errors = rc.getErrors("");
Preci toto je spravne misto, pokud uz treba existuje dany user, jak
dat ty informace do Errors. Pripadne me napada, ze bychom mohli
usetrit jednu tridu navic. Validator. ...
Pet
Roman Pichlík napsal(a):
Burdik Petr napsal(a):
Pekne rano,
od vcerejska se mi nedari vyresit validaci vramci
multiActionControlleru. Rad bych aby to byla rucni validace.
Problem je ze se mi nedari najit, jak vytvorit a hlavne do view
pridat kolekci errors. Upozornuji ze jsem si vedom ze errors je
jen interface. Nechce se mi totiz pro kazdou metodu kterou
provadim tvorit extra tridu validatoru. Nejvice se chci priblizit
tomu jak to ma struts.
Tedy:
1. multiactioncontroller s nejcasteji curl metodami
2. actionform se vsemi formularovymi promennymi
3. metoda / metody pro validaci, podle provadene akce
Errors model by mel zaregiastrovat controller automaticky pokud
neprojde request validaci.
V JSPcku se na nej pak staci bindnout pres
<spring:bind path="command">
<c:forEach items="${status.errorMessages}" var="errorMessage">
<c:out value="${errorMessage}"/> </c:forEach>
command je defaultni jmeno command objektu viz
http://static.springframework.org/spring/docs/1.2.x/api/org/springframework/web/servlet/mvc/multiaction/MultiActionController.html#getCommandName(java.lang.Object)
--
S pozdravem Roman "Dagi" Pichlik
/* http://www.sweb.cz/pichlik/ Blog pro kodery */