- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 MethodInterceptor
方面和 @Validated
注释有一个奇怪的问题。当我添加方法拦截器来拦截所有使用@RequestMapping
注释的方法时,@Validated
注释不起作用。当我删除它时,它又可以正常工作了。我认为,我的拦截器覆盖了@Validated。有什么方法可以做到这一点,因为我不想在拦截器中执行验证,因为它是用于审核内容的。
这是 validator :
@Component
public class UserValidator implements Validator {
@Override
public void validate(Object target, Errors errors) {
//validation stuff
}
}
Controller 的代码:
@Controller
@RequestMapping("/profile")
public class UserProfileController {
@Autowired
private UserValidator userValidator;
@InitBinder("userValidator")
private void userValidatorInitBinder(WebDataBinder binder) {
binder.setValidator(userValidator);
}
@RequestMapping(value = "/reg.do", method = RequestMethod.POST)
public @ResponseBody RegisterResponse reg(HttpServletRequest httpServletRequest, @RequestBody @Validated CreateUserRequest createUserRequest) {
}
}
拦截器代码:
@Aspect
@Component
public class MyInterceptor implements MethodInterceptor, Serializable {
@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object returnValue = null;
final StopWatch stopWatch = new StopWatch();
try {
stopWatch.start();
returnValue = invocation.proceed();
return returnValue;
} catch (Throwable ex) {
stopStopwatch(stopWatch);
throw ex;
} finally {
System.out.println(stopwatch);
}
}
}
我的环境是带有休息 Controller (Jackson Mapper)的 Spring MVC (3.2)。
最佳答案
问题是使用基于代理的 AOP,在本例中,由于不存在接口(interface),它是基于类的代理。作为@RequestBody
和@Validated
方法不是继承的,它们不存在于重写该方法的子类中。因此不再有@Validated
.
为了解决这个问题,(对于这种情况)有几个解决方案。
HandlerInterceptor
而不是 AOPApplicationListener
它听 ServletRequestHandledEvent
s由于这只是一个性能测量,因此使用选项 1 和 2 很容易做到。选项 3 可能相当具有侵入性,选项 4 取决于所使用的 servlet 容器。
HandlerInterceptor
但是,由于这只是一个性能测量,并且适用于处理程序而不是 AOP,因此我建议使用 HandlerInterceptor
这将从 preHandle
开始计时并以 afterCompletion
结尾方法。
public class PerformanceMeasureInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
StopWatch sw = new StopWatch();
sw.start();
request.setAttribute("performance-measure-sw", sw);
return true;
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
StopWatch sw = (StopWatch) request.getAttribute("performance-measure-sw");
if (sw != null) {
sw.stop();
System.out.println(sw);
}
}
}
ApplicationListener<ServletRequestHandlerEvent>
作为 DispatcherServlet
已经监视处理请求所需的时间,并在处理请求后触发 ServletRequestHandledEvent
其中包含处理所花费的时间。您可以创建一个 ApplicationListener
它监听事件并将一行写入日志文件(或控制台)。
@Component
public class PerformanceListener implements ApplicationListener<ServletRequestHandledEvent> {
public void onApplicationEvent(ServletRequestHandledEvent event) {
System.out.println("Processing: " + event.getRequestUrl() + ", took: " + event.getProcessingTimeMillis + "ms. ");
}
}
当使用加载时编织时,类的字节码会在类加载后立即修改,因此无需为该类创建代理。这允许 @Validated
仍然继续工作。
根据所使用的 servlet 容器,它可能就像替换 <aop:aspectj-autoproxy />
一样简单或@EnableAspectJAutoProxy
与 <context:load-time-weaving />
或@EnableLoadTimeWeaving
。对于其他容器,需要设置 javaagent 以允许发生加载时编织。欲了解更多信息,请查看reference guide
使用编译时编织时,类的字节码会在项目的编译阶段进行修改。这需要修改您的编译和 ajc
的使用(AspectJ 编译器)。这可能很难工作,您可能需要检查 Compile time weaving for DI in non-spring managed classes了解更多相关信息。
你的 Aspect 很奇怪,因为它混合了 2 种不同风格的 AOP。首先它使用 AspectJ,其次它尝试成为 aopalliance MethodInterceptor
。尽量不要混合使用方法,因为这可能会导致奇怪的问题。
我建议坚持使用 AspectJ,所以尝试修改你的 Aspect,你可能还想添加 stopStopWatch
方法到finally而不是仅到catch
block 。
@Aspect
@Component
public class MyInterceptor {
@Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
Object returnValue = null;
final StopWatch stopWatch = new StopWatch();
try {
stopWatch.start();
returnValue = pjp.proceed();
return returnValue;
} catch (Throwable ex) {
throw ex;
} finally {
stopStopwatch(stopWatch);
System.out.println(stopwatch);
}
}
}
您可能想查看 spring 已经提供的 spring 性能拦截器,而不是自己动手。您可能想使用 AbstractMonitoringInterceptor
的子类之一而不是你自己的。 (虽然这不能帮助您解决代理问题,但可以帮助您维护自己的性能拦截器)。
关于java - @RequestMapping MethodInterceptor 方面忽略 @Validated 注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25863782/
如何在Spring中忽略类级别@RequestMapping("/home")并直接调用方法级别@RequestMapping("/users")? @Controller @RequestMappi
让我们假设以下 Controller : @RestController public class MyController { @RequestMapping(method = GET, pat
我在使用 Spring Boot 时遇到了一些问题。 当我使用 @RequestMapping(value = "/home") 时,一切正常。但是当我使用 @RequestMapping(name
我正在尝试创建一个restful API(使用Spring Boot v2.0.0.Release),我希望有一个端点,但我希望有两种可能的用途: GET /time - outputs curren
我已经被这个错误困扰了几个小时。。我的pom.xml。应用程序未启动。所有的Spring框架依赖于相同的版本,但仍然得到相同的错误。。更新。MVN依赖的结果:树。看起来这里一切都很好。
我有以下三个 REST API 方法: @RequestMapping(value = "/{name1}", method = RequestMethod.GET) public Objec
我正在尝试为 spring @RequestMapping 注释创建值属性以像这样映射 url /educationDistrict/308/action/resetAddressesForYear/
如何定义 @RequestMapping 方法来显式允许匿名(未经授权)访问? 以下方法不起作用,总是收到 401 Unauthorized: @RequestMapping("/test") @Se
想象一下我有一个像这样的 Spring MVC Controller : @Controller @RequestMapping("/base-url") public class MyControl
如何处理除资源映射文件夹之外的所有 URL 请求? 在这个例子中,我处理了所有路径(这就是我想要的),但现在即使我设置也无法访问资源文件夹 里面dispatcher-servlet.xml @Req
我需要有一个/jsp/login 和/jsp/login?error 的映射 请注意,我无法使用/jsp/login?error=someval 然后检查参数是否具有该值或默认值。在这种情况下,不允许
让 Tomcat 启动并自动显示 index.jsp 文件的内容没有任何问题。然而,当我尝试使用 @Controller 和 @RequestMapping 时,我遇到了错误。这是我的 Control
我有以下文件夹结构: WEB-INF/ -- 页数/ ----home.jsp ----admin.jsp ----admin2.jsp ----admin3.jsp 我有以下 Controller
我正在使用 Spring Boot,并尝试显示 get 请求。我正在使用 2 个类:Greeting.java 和 GreetingController: package greeting;
我正在尝试使用 @RequestMapping与 consumes -元素。阅读API-document它适用于 Content-Type - 请求头。但是,使用 @RequestMapping(co
我已经为此打开了一个问题 here.但我也想问一下 stackoverflow 的人。 @Controller @RequestMapping("/xxx") public class MyContr
我想在我的 Spring Boot 应用程序中创建一个自定义注释,它总是向我的类级别 RequestMapping 路径 添加一个前缀。 我的 Controller : import com.sage
鉴于下面的@Controller,即使我向 webApp 发送 Get 请求, Controller 也会运行 homePage 方法。 @RestController @RequestMapping
我正在尝试设置 Controller ,但不幸的是无法查看输出...一切都正确渲染。当我访问 http://localhost:8080/CMT/content/edit 时,我得到一个 404 页面
在我的 Spring Controller 中,我创建了 3 个方法。方法 1 和方法 2 工作正常,但方法 3 给我带来问题 问题: org.springframework.web.servlet.
我是一名优秀的程序员,十分优秀!