0

当我们配置 Spring AOP 时,JSON 结果消失:AOPExression1

<aop:pointcut id="dmhMethodExecution"
            expression="within(com.aditya.dmh..*)" />

所以我添加了一个排除项:AOPExpression1 as AOPExpression2

<aop:pointcut id="dmhMethodExecution"
   expression="within(com.aditya.dmh..*) 
        and !within(com.aditya.dmh.controller..*)" />

在 ASPECTJ 表达式中,我仍然看不到来自控制器的 JSON 结果,这是一个安静的实现。

package com.aditya.dmh.controller;

@Controller
public class EmployeeController {

private EmployeeServiceInterface employeeService;

@Autowired
public void setEmployeeService(EmployeeServiceInterface employeeService) {
    this.employeeService = employeeService;
}

@RequestMapping("/employeeservices/1/allemployees.view")
public @ResponseBody Result<EmployeeModel> getEmployees(){
    return employeeService.getEmployees(0, 10);

}
}

当我将 log4j 用于调试消息时,我看到以下内容:

15:37:04.214 [http-8090-1] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView  returned to DispatcherServlet with name 'dmhServiceDispatcher': assuming HandlerAdapter completed request handling

15:37:04.214 [http-8090-1] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request

当我删除 AOP 时,JSON 结果开始出现,我看到附加的调试消息。

17:11:36.270 [http-8090-2] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.aditya.Result@8a85268] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@62ba2e48]

查看 Spring 论坛,我了解转换器是自动配置的,当

<mvc:annotation-driven/>

用来。

我配置 AOP 的问题是否与未调用 RequestResponseBodymethodProcessor 有任何关系。

这与我使用 AOPExpression1 时在我的控制器周围创建的代理有什么关系吗?为什么 AOPExpression2 中的排除仍然存在问题。

任何帮助,将不胜感激

4

3 回答 3

0

在这种情况下我们的问题的解决方案

我们发现整个事情都与我们所拥有的 AOP 配置中的环绕建议有关。

修复前

public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    long startTime = System.currentTimeMillis();
    joinPoint.proceed();
    long totalTime = System.currentTimeMillis() - startTime;

    log.debug(buildLogMessage(new StringBuilder().append(METHOD_AROUND_ID)
            .append("[").append(totalTime).append("] ").toString(),
            joinPoint));
    return returnValue;
}

修复后

public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    long startTime = System.currentTimeMillis();
    Object returnValue = joinPoint.proceed();
    long totalTime = System.currentTimeMillis() - startTime;

    log.debug(buildLogMessage(new StringBuilder().append(METHOD_AROUND_ID)
            .append("[").append(totalTime).append("] ").toString(),
            joinPoint));
    return returnValue;
}

void 有效地确保 logAround 发送的响应对象没有传递回 RequestResponseBodyMethodProcessor

一旦我们将其捕获并返回,cglib 代理就会将响应发送回处理器并将响应发送回客户端。

于 2012-09-03T06:49:36.690 回答
0

我相信要拦截对控制器的请求,您应该使用 MVC 拦截器而不是方面。我所做的是将以下内容放入 applicationContext.xml:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/employeeservices/1/allemployees.view"/>
        <bean class="com.aditya.dmh.interceptor.ResultInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

现在,类 ResultInterceptor 是您放置要完成的代码的地方,例如:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    log.info("--- preHandle --- ");

    return true;
}

至少我是这样做的。

希望能帮助到你。

于 2012-08-30T13:02:24.907 回答
0

这是一个小小的猜测:

我认为正在发生的事情是为您的控制器创建了一个基于 CGLIB 的动态代理(尽管您已经在新的切入点表达式中明确排除了它),如果发生这种情况,则@RequestMapping无法正确检测到注释(通过 `),因此控制器不是在那里处理您的 REST 请求。

你可以尝试一些事情:

  1. 为控制器提供一个与控制器处理的方法完全相同的接口,并将@RequestMapping注释放在那里,这将处理创建动态代理的情况,即使创建了动态代理也应该按预期工作。

  2. 多玩一点你的切入点表达式,看看为什么会为你的控制器创建一个代理。

于 2012-08-30T13:25:36.537 回答