Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Witam, zaczynam naukę SpringMVC i podczas walidacji danych wyskakuje taki błąd:

javax.validation.ConstraintViolationException: Validation failed for classes [pl.pawel.spring.model.Contact] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='size must be between 5 and 2147483647', propertyPath=lastname, rootBeanClass=class pl.pawel.spring.model.Contact, messageTemplate='{javax.validation.constraints.Size.message}'}
]
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:161)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94)
org.hibernate.action.EntityInsertAction.preInsert(EntityInsertAction.java:178)
org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:72)
org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)
org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
$Proxy42.addContact(Unknown Source)
pl.pawel.spring.controller.ContactController.addContact(ContactController.java:41)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:601)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:436)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:424)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:322)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:184)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:155)
org.springframework.security.config.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:69)
org.springframework.security.config.debug.DebugFilter.doFilter(DebugFilter.java:58)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)


Widzę, że błąd jest w metodzie
addContact(Contact c)

ale nie wiem jak go naprawić.

Klasy zawarte w projekcie:
Model
@Entity
@Table(name = "contacts")
public class Contact implements Serializable {
@Id
@GeneratedValue
private Integer id;

private String firstname;

@NotNull
@Size(min = 5)
private String lastname;

//gettery i settery
}


@Repository
public class ContactDAOImpl implements ContactDAO {

@Autowired
public SessionFactory sessionFactory;

@Override
public void addContact(Contact contact) {
sessionFactory.getCurrentSession().save(contact);
}

//pozostałe metody
}

@Service
public class ContactServiceImpl implements ContactService {

@Autowired
private ContactDAO contactDAO;

@Transactional
public void addContact(Contact contact) {
contactDAO.addContact(contact);
}
}


Kontroler
@Controller
public class ContactController {

Logger log = LoggerFactory.getLogger(ContactController.class.getName());

@Autowired
private ContactService contactService;

@RequestMapping("/")
public String listContacts(Map<String, Object> map) {

map.put("contact", new Contact());
map.put("contactList", contactService.listContact());

return "contact";
}

@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addContact(@Valid Contact contact, BindingResult result) {

contactService.addContact(contact);
return "redirect:/";
}
}

Formularz w widoku

<form:form method="post" action="add" commandName="contact"
modelAttribute="contact">
<table>
<tr>
<td><form:label path="firstname">
<spring:message code="label.firstname" />
</form:label></td>
<td><form:input path="firstname" /></td>
</tr>
<tr>
<td><form:label path="lastname">
<spring:message code="label.lastname" />
</form:label></td>
<td><form:input path="lastname" /></td>
<td><form:errors path="lastname" cssClass="error" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit"
value="<spring:message code="label.addcontact"/>" /></td>
</tr>
</table>
</form:form>


Do konfiguracji Spring'a dodałem:
<bean class="pl.pawel.spring.service.ContactServiceImpl" id="contactService"/>
<bean class="pl.pawel.spring.dao.ContactDAOImpl" id="contactDAO"/>


Dlaczego komunikat o błędzie nie wyświetla się w
<td><form:errors path="lastname" cssClass="error" /></td>


Jakieś sugestie co może być źle?
Łukasz Kwiatkowski

Łukasz Kwiatkowski Programista Java

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Przy testowaniu formularza prawdopodobnie wpisujesz lastname krótsze niż 5 znaków.
Chodzi o adnotację @Size(min = 5) nad polem lastname w klasie Contact.

'size must be between 5 and 2147483647', propertyPath=lastname, rootBeanClass=class pl.pawel.spring.model.Contact
Maciej Nowicki

Maciej Nowicki Java Developer

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

A co ma być źle? Masz adnotację @Size(min=5) przy property lastname, a pewnie nic (albo wartość któtszą niż 5 znaków) tam nie wpisujesz
Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Łukasz K.:
Przy testowaniu formularza prawdopodobnie wpisujesz lastname krótsze niż 5 znaków.
Chodzi o adnotację @Size(min = 5) nad polem lastname w klasie Contact.

'size must be between 5 and 2147483647', propertyPath=lastname, rootBeanClass=class pl.pawel.spring.model.Contact
wiem, tylko dlaczego komunikat tego błędu nie wyświetla się w formularzu w komórce:
<td><form:errors path="lastname" cssClass="error" /></td>
Łukasz Kwiatkowski

Łukasz Kwiatkowski Programista Java

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Sorki nie doczytałem pytania.
1. Ustaw path="*" i zobacz czy działa
2. Sprawdź czy w DOM strony (użyj np. firebuga ) pojawił się element z błędem
3. Sprawdź czy nie masz jakiejś literówki
4. Porównaj swój kod z tym: http://www.mkyong.com/spring-mvc/spring-mvc-form-error...Ten post został edytowany przez Autora dnia 12.06.13 o godzinie 15:05
Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Dalej to samo, już nie mam pomysłu gdzie może być błąd. Podany przykład jest ze strony
http://viralpatel.net/blogs/spring3-mvc-hibernate-mave...
i chcę do formularza dodawania kontaktów dodać walidację danych.
Ma ktoś jakieś sugestie jak to zrobić?

konto usunięte

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Dla walidacji sprobuj moze cos takiego (formularz => strona, gdzie walidacja jest analizowana => powrot do strony formularza w wypadku bledu albo redirect do strony z wiadomoscia o poprawnym dodaniu formularza) :

@RequestMapping("/question")
@Controller
public class QuestionController extends MainController {
final Logger logger = LoggerFactory.getLogger(QuestionController.class);
private final String addBinding = "org.springframework.validation.BindingResult.question";
// ...

@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = "/write", method = RequestMethod.GET)
public String write(@ModelAttribute("question") Question question,
@LoggedUser AuthenticationFrontendUserDetails user, Model layout, HttpServletRequest request,
@LocaleLang Lang lang) {
Map<String, Object> layoutMap = layout.asMap();
if (layoutMap.containsKey("errors")) {
layout.addAttribute(addBinding, layoutMap.get("errors"));
}
// ...
return "questionWrite";
}

@PreAuthorize("hasRole('ROLE_USER')")
@RequestMapping(value = "/write", method = RequestMethod.POST)
public String writeHandle(@ModelAttribute("question") @Validated({GeneralGroupCheck.class}) Question question, BindingResult binRes,
@LoggedUser AuthenticationFrontendUserDetails user, RedirectAttributes redAtt, @LocaleLang Lang lang) {
logger.info("Received POST request " + question);
if (binRes.hasErrors()) {
redAtt.addFlashAttribute("error", true);
redAtt.addFlashAttribute("question", question);
redAtt.addFlashAttribute("errors", binRes);
} else {
// Dodaje do bazy itd.
}
return "redirect:/question/write";
}
}

(ten przyklad i kilka innych znajdziesz tutaj : https://github.com/bartosz25/library-sample-project/blo...Ten post został edytowany przez Autora dnia 13.06.13 o godzinie 15:53
Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Hej, a mógłby ktoś napisać co należy zrobić krok po kroku aby używać walidacji danych w formularzu, może wtedy znajdę błąd u mnie?
Tomasz Szymański

Tomasz Szymański Lead Java Developer,
Bravura Solutions

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Na moje oko Ty nie sprawdzasz w ogóle wyniku walidacji. Czy jest dobrze, czy źle - wywołujesz contactService.addContact(contact);
Musisz swoją metodę ContactController.addContact trochę rozbudować - na wzór tego, co wkleił Bartosz. Jeśli BindingResult ma błędy, to przygotować model i pokazać ponownie formularz. Jeśli nie ma, to zapisać contact.
Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Hej, do konfiguracji Spring'a dodałem bean'a i teraz już nie sypie błędem
javax.validation.ConstraintViolationException

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<!-- Configures Spring MVC DataBinder instances -->
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator"/></bean></property></bean>

<bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" id="validator"/>

zmodyfikowałem trochę funkcje ContactController.addContact tak, aby w przypadku wystąpienia błędów wyświetlić formularz raz jeszcze, jednak komunikat o błędzie nadal się nie wyświetla w formularzu.
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addContact(@ModelAttribute("contact") @Valid Contact contact, BindingResult result) {
if (result.hasErrors()) {
System.out.println("ERROR: " + result.hasErrors());
for (ObjectError e : result.getAllErrors()) {
System.out.println(e.getDefaultMessage());
}
return "redirect:/";
}
contactService.addContact(contact);
return "Done";
}

W DOM strony w ogóle nie pojawia się element z błędem, co widać na obrazku:

Obrazek

Co może być powodem takiej sytuacji?
Tomasz Szymański

Tomasz Szymański Lead Java Developer,
Bravura Solutions

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Paweł K.:
Co może być powodem takiej sytuacji?

Myślę, że teraz powodem jest to, że do wyświetlenia formularza w przypadku błędów używasz redirecta. Nie wiem czy wiesz jak działa redirect, ale do Twojego celu się nie nadaje. Powinieneś prawdopodobnie zwrócić po prostu nazwę widoku formularza, czyli u Ciebie "contact".
Tyle, że z Twojego kodu, który zacytowałeś na początku, widzę, że ten widok wymaga jeszcze w modelu atrybutu "contactList", więc być może powinieneś tę listę jeszcze doładować.
Paweł Koźbiał

Paweł Koźbiał Student,
Politechnika
Częstochowska

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Tomasz S.:
Paweł K.:
Co może być powodem takiej sytuacji?

Myślę, że teraz powodem jest to, że do wyświetlenia formularza w przypadku błędów używasz redirecta. Nie wiem czy wiesz jak działa redirect, ale do Twojego celu się nie nadaje. Powinieneś prawdopodobnie zwrócić po prostu nazwę widoku formularza, czyli u Ciebie "contact".
Tyle, że z Twojego kodu, który zacytowałeś na początku, widzę, że ten widok wymaga jeszcze w modelu atrybutu "contactList", więc być może powinieneś tę listę jeszcze doładować.

Poprawiłem według twoich wskazówek i działa:
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addContact(@ModelAttribute("contact") @Valid Contact contact,
BindingResult result, ModelMap map) {

if (result.hasErrors()) {
map.put("contactList", contactService.listContact());
return "contact";
}
contactService.addContact(contact);
map.put("contactList", contactService.listContact());
return "Done";
}

Mógłbyś wyjaśnić jak działa i kiedy należy używać redirect?
Tomasz Szymański

Tomasz Szymański Lead Java Developer,
Bravura Solutions

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Paweł K.:
Mógłbyś wyjaśnić jak działa i kiedy należy używać redirect?

Tak w skrócie mówiąc - redirect to taka króciutka odpowiedź do przeglądarki, która zmusza ją do wysłania kolejnego żądania. Więc jeśli Ty wysyłałeś redirect z adresem "/", to tak, jakbyś mówił przeglądarce: zapomnij o wyniku poprzedniego żądania, ściągnij zasób spod adresu "/". No to przeglądarka tak robi i ściąga nowym żądaniem czysty formularz.
Teraz, kiedy zwracasz "contact", Spring generuje w odpowiedzi "normalną" treść w oparciu zapewne o jakiś contact.jsp - ciągle w ramach tego samego żądania, w którym nastąpiła walidacja, a więc mając pod ręką w modelu cały jej wynik.
Nie wiem na ile to jasno brzmi. Zawsze możesz spojrzeć np. tu: http://en.wikipedia.org/wiki/URL_redirection ;-) Wśród zastosowań zwróć uwagę szczególnie na http://en.wikipedia.org/wiki/Post/Redirect/Get
Krzysztof T.

Krzysztof T. Umysł nie jest
naczyniem, które
trzeba napełnić,
lecz ogn...

Temat: [SpringMVC, JSP] Błąd podczas walidacji danych

Paweł K.:
Hej, a mógłby ktoś napisać co należy zrobić krok po kroku aby używać walidacji danych w formularzu, może wtedy znajdę błąd u mnie?

Jak uczyłem się Springa MVC miałem też ten sam problem. Żeby poprawnie zadziałał dla Ciebie mechanizm walidacji danych, to na wywołanie metody .GET przy wyświetlaniu formularza musisz utworzyć i przekazać instancję klasy (commandName="klasa" , albo attributeName) z podpiętymi validatorami i przekazać ją do formularza po stronie przeglądarki.
W momencie próby wysłania formularza z błędem wtedy wyświetlą się błędy. W oknie tak jak chcesz a nie stacktrace w przeglądarce/konsoli



Wyślij zaproszenie do