gpt4 book ai didi

在 Controller 方法之前调用 Spring mvc 验证异常处理程序

转载 作者:行者123 更新时间:2023-12-04 07:02:14 25 4
gpt4 key购买 nike

我有以下代码:

public class StudentController extends BaseController {

@RequestMapping(value = "/student/edit", method = RequestMethod.POST)
public String submitForm(@Valid @ModelAttribute(MODEL_ATTRIBUTE_STUDENT) StudentDTO edited,
BindingResult bindingResult, RedirectAttributes attributes) {
if (bindingResult.hasErrors()) {
return STUDENT_EDIT_FORM_VIEW;
}

//some logic...
}

@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
dateFormat.setLenient(false);

// true passed to CustomDateEditor constructor means convert empty String to null
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
}

public class BaseController {
@ExceptionHandler(Exception.class)
protected ModelAndView handleAllException(Exception ex) {
Long errorId = System.currentTimeMillis() + RandomInteger.generate(1, Integer.MAX_VALUE);

//do something...

Map<String, String> parameters = new HashMap<>();
parameters.put("flash_message", "Things blew up...!");

return new ModelAndView("/errorpage", parameters);
}
}

现在,当出现绑定(bind)错误时(例如在用户输入 2013 年 2 月 40 日的日期字段中),我希望执行以下 block :
if (bindingResult.hasErrors()) {
return STUDENT_EDIT_FORM_VIEW;
}

而是执行 ExceptionHandler 并返回 errorpage.html ..!

我没有在 View 中使用 Spring 标签(表单:表单)。我正在使用 thymeleaf + boostrap + jquery
编辑:
这是所要求的异常(exception) -
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'student' on field 'responseDate': rejected value [02/30/2014]; codes [typeMismatch.student.responseDate,typeMismatch.responseDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.responseDate,responseDate]; arguments []; default message [responseDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'responseDate'; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: "02/30/2014"]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:110)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)

StudentDTO 类有一堆学生需要输入的日期。如下所示
public class StudentDTO {
private Long id;
private String state;
private String region;
private Date responseDate;
private Date stayLiftedDate;
...
...
//Then all getters and setters.
}

编辑2:

如果我从 basecontroller 的 handleAllException() 方法抛出错误并记录堆栈跟踪,会发生以下情况
java.lang.Exception: Sample Error
at com.mycompany.controller.BaseController.handleAllException(BaseController.java:103)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:321)
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60)
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:136)
at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:73)
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1148)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:985)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at com.mycompany.security.CookieAuth.doFilter(CookieAuth.java:50)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)

最佳答案

您会注意到在 ModelAttributeMethodProcessor#resolveArgument(..) 处引发了异常。它发生在这里

if (binder.getBindingResult().hasErrors()) {
if (isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}

因此,如果解析日期参数时出错(或任何其他错误)并且 isBindExceptionRequest(..) 返回 true,则 BindingResult 将被包装在 BindException 中并抛出。那么 isBindExceptionRequires(..) 是什么?

它是这样实现的
protected boolean isBindExceptionRequired(WebDataBinder binder, MethodParameter parameter) {
int i = parameter.getParameterIndex();
Class<?>[] paramTypes = parameter.getMethod().getParameterTypes();
boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));

return !hasBindingResult;
}

as the Javadoc says

Returns: true if the next method argument is not of type Errors.



换句话说,如果您的处理程序方法是这样声明的
public String submitForm(@Valid @ModelAttribute(MODEL_ATTRIBUTE_STUDENT) StudentDTO edited,
BindingResult bindingResult, RedirectAttributes attributes) {
BindException 不会被抛出,因为在 Errors 参数旁边有一个 BindingResult 类型的参数( @ModelAttribute 是一个子类型)。

这意味着您正在从其他一些处理程序方法中获取异常,其中命令对象参数后面没有 BindingResult。或者您的配置中还有其他一些您没有向我们展示的内容。

关于在 Controller 方法之前调用 Spring mvc 验证异常处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22003011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com