2012-04-04 24 views
5

Najnowsza wiosna mvc, za pomocą freemarker.Mylił się, jak sprawdzić wiosenny formularz mvc, jakie mam opcje?

nadzieję, że ktoś mógłby mi powiedzieć, jakie są moje możliwości są w zakresie walidacji formularza z wiosny MVC, a co polecić sposób byłoby to zrobić.

Mam formularz, który nie jest mapowany bezpośrednio do modelu, ma pola wejściowe, które po wysłaniu będą używane do zainicjowania 2 obiektów modelu, które następnie będę musiał zweryfikować, a jeśli przejdą, będę je zapisywać .

Jeśli tego nie chcę, aby wrócić do formy, wstępnie wypełnić wartości co wszedł użytkownik i wyświetla komunikaty o błędach.

mam przeczytać tutaj i tam około 2 metody, które kiedyś zrobiłem i zrozumieć, jak to działa:

@RequestMapping(...., method = RequestMethod.POST) 
public ModelAndView myMethod(@Valid MyModel, BindingResult bindingResult) { 
    ModelAndView mav = new ModelAndView("some/view"); 
    mav.addObject("mymodel", myModel); 

    if(bindingResult.hasErrors()) { 
    return mav; 
    } 

} 

Teraz to działało jeśli moja forma odwzorowane bezpośrednio do formy, ale w mojej sytuacji mam ma:

  1. pól formularza, które nie są mapowane do żadnego konkretnego modelu, mają kilka właściwości z 2 modeli.

  2. przed occurrs walidacja, muszę ręcznie tworzyć modele 2, ustawić wartości z formularza i ręcznie ustawić pewne właściwości również:

  3. połączeń validate w obu modelach (model1, MODEL2) oraz dołączyć te komunikaty o błędach do kolekcji błędów, które muszę przekazać z powrotem do tej samej strony widoku, jeśli coś nie działa.

  4. kiedy słupki forma, muszę zrobić kilka połączeń z bazą danych, a na podstawie tych wyników może trzeba dodać dodatkowe komunikaty do kolekcji błędów.

Czy ktoś może mi powiedzieć, jak wykonać tego rodzaju weryfikację?

Pseudo kod poniżej:

Model1 model1 = new Model1(); 
    Model2 model2 = new Model2(); 

    // manually or somehow automatically set the posted form values to model1 and model2. 

    // set some fields manually, not from posted form 
    model1.setProperty10(GlobalSettings.getDefaultProperty10()); 
    model2.setProperty11(GlobalSettings.getDefaultProperty11()); 

    // db calls, if they fail, add to errors collection 

    if(bindingResult.hasErrors()) { 
    return mav; 
    } 

    // validation passed, save 
    Model1Service.save(model1); 
    Model2Service.save(model2); 

    redirect to another view 

Aktualizacja

Mam użyciu JSR 303 adnotacje na moich modeli teraz, i byłoby wspaniale, jeśli mogę użyć tych nadal.

Aktualizacja II

Proszę przeczytać poniższy opis nagród na podsumowanie tego, co szukam.

Odpowiedz

8

Na podstawie podobnych doświadczeń, chciałbym zaproponować następujące iz boku mam komentarz na ostatnim etapie na podejściu, które chcesz podjąć. Używam Twojej numerowanej listy kroków.

Krok 1: Formularz Bean

Istnieją dwa sposoby na to.Prostym rozwiązaniem jest zdefiniowanie fasoli forma (przypuszczam że już zrobione):

class MyModel { 
    private Model1 model1; 
    private Model2 model2; 
    // standard Java bean stuff 
} 

Bardziej precyzyjny sposób to rzeczywiście określić MyModel taka, że ​​ja tylko pożycza pola, które wymaga od Model1 i Model2 ale Nie jestem pewien, czy to pasuje do ciebie.

Krok 2: Wiązanie danych

Wiosna robi to dla ciebie, jeśli masz taką form strukturę w widoku:

<form:form modelAttribute="myModel"> 
    <form:input path="model1.somePropertyToBeSet" /> 
</form:form> 

Krok 3: Walidacja

Używając Spring custom validations, możesz zdefiniować cust Ograniczenia om:

@interface Model1Constraint {} 
@interface Model2Constraint {} 

class MyModel1 { 

    @Model1Constraint 
    private Model1 model1; 

    @Model2Constraint 
    private Model2 model2; 

    // ... 

} 

następnie zarejestrować niestandardowe Walidatory dla ograniczeń niestandardowych:

class Model1ConstraintValidator implements ConstraintValidator<Model1Constraint, Model1> { 
// implementation of isValid and initalize 
} 

i to samo dla Model2Constraint. Korzystając z niestandardowych weryfikatorów, można sprawdzić, jaka logika jest potrzebna, aby przed przekazaniem MyModel przejść do metody przetwarzania żądania. Zakładam również, że użyłeś <mvc:annotation-driven />, aby Spring zarejestrować walidatory; w przeciwnym razie powinieneś je skonfigurować.

Krok 4: Przetwarzanie modelu klienta przed przetwarzania żądania

Twój oryginalny pomysł jest użycie jakieś spoiwo danych do tej pracy. W swoim opisie wspominasz również, że przetwarzanie danych nie zależy od danych pochodzących z danych formularza.

Jeśli chodzi o projektowanie i modułowość, nie wierzę, że segregator danych jest dobrym miejscem do tego celu. Po drugie, ponieważ nie istnieje zależność danych od formularza, głównym powodem jest umożliwienie przetwarzania błędów wiązania danych.

Moja sugestia polega na tym, że teraz jesteś w public ModelAndView myMethod(@Valid MyModel model, BindingResult bindingResult). Prawdopodobnie masz tutaj dostęp do innych komponentów usługowych. W niektórych komponentach usługi może być dostępna metoda, która może refine lub prepare (tylko nazwy) model, które zostały wypełnione w tym punkcie. Na podstawie wyjątków lub dowolnego innego mechanizmu, który Ci odpowiada, możesz użyć bindingResult, aby ponownie zwrócić błędy.

Jako kolejna sugestia, możesz również skorzystać z Spring interceptors, jeśli chcesz uzyskać więcej DI/IoC sposób, aby to zrobić. Ale w ten sposób powinieneś wyodrębnić MyModel z ModelAndView w przechwyceniu i kontynuować.

Mam nadzieję, że to pomoże.

0

Hibernate Validator 4.2 obsługuje sprawdzanie poziomu metod. Możesz trochę skorygować swój kod, aby przekazać dwa modele w metodzie i zatwierdzić je.

http://java.dzone.com/articles/method-validation-spring-31

można mieć coś takiego

public void persistUser(@NotNull @Valid Model1 model1, @NotNull @Valid Model2 model2) { 

     //continue ... 
} 
0

Jest to niezwykły problem, jak to zwykle największy sens do sprawdzania poprawności danych wejściowych użytkownika, jak to jest dane nie możemy kontrola. Skoro już o tym mówiłem, a jestem pewien, że już to wiesz ...

Jedną opcją byłoby użycie aplacji sprawdzania poprawności JSR 303 bezpośrednio w celu sprawdzenia poprawności obiektów modelu po ich wypełnieniu przez dane wejściowe użytkownika, bazę danych itp ..

Oto przykład:

@RequestMapping(value=...) 
public String myMethod(MyForm form, Model m) { 

    ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
    Validator validator = factory.getValidator(); 

    Model1 model1 = createModel1FromUserInput(form); 
    Model2 model2 = createModel2FromUserInput(form); 

    Set<ConstraintViolation<?>> modelViolations = validator.validate(model1); 
    modelViolations.add(validator.validate(model2)); 
    if(modelViolations.size() != 0) { 
     m.addAttribute("violations", modelViolations); 
     m.addAttribute("form", myForm); // add the form back to the model so it is populated 
     return "formPage"; 
    } 
    return "successPage"; 
} 

Możesz wolą wiązać się z wiosennym BindingResult lub zbioru błędów. Nie testowałem poniższy kod, a nie jestem bardzo wygodne pracy bezpośrednio z BindingResult, więc będzie wymagać szczypanie:

BindingResult result = ... // not sure about the constructor 
for(ConstraintViolation<?> violation : modelViolations) { 
     result.addError(new ObjectError(violation.getPropertyPath().toString(),violation.getMessage())); 
} 

Jeśli dopiero próbuje wypluć błędów na JSP, a następnie za pomocą Set<ConstraintViolation> mogą działać wystarczająco dobrze dla swoich potrzeb:

<c:forEach items="${violations}" var="violation"> 
    ${violation.propertyPath}: ${violation.message} <br/> 
</c:forEach> 

Jeśli próbujesz użyć <form:errors> tag Wiosny, musisz użyć wynik wiązania.

HTH! Daj mi znać, jeśli masz więcej pytań. Lub jeśli całkowicie pominąłem znak w tej odpowiedzi, spróbuję wyjaśnić.

Powiązane problemy