当前位置: 首页 > 知识库问答 >
问题:

为什么不能使用spring AOP更改响应类型(返回对象除外)

佟阳云
2023-03-14

我正在使用Spring AOP来点切我的控制器方法,并尝试将公共结构响应返回到前端。定义如下:

public class CommonResponse {

private String status;

private String message;

private Object data;
}

我还有一个点定义如下:

@Aspect
@Component
public class PostMessageInterceptor {


@Pointcut("within(org.moa.controller.*)")
public void postMessageConvert() {}

@Around("postMessageConvert()")
public CommonResponse modifyResult(ProceedingJoinPoint pjp) {
    CommonResponse response = new CommonResponse();
    try {
        Object result = pjp.proceed();
        response.setStatus("success");
        response.setData(result);
    }catch(Throwable t) {
        response.setStatus("failure");
        response.setMessage(t.getMessage());
    }
    return response;
}
}

例如,当控制器返回类型中的方法为map 时,在执行modifyresult后,返回类型从map 转换为CommonResponse时,则Spring AOP将出现异常java.lang.ClassCastException:CommonResponse不能转换为java.util.map

如果我将此方法的返回类型更改为Object,它将正常工作。

我只想知道这是设计成这样的吗?否则,有没有任何方法,我可以实现这个目标,而不修改返回类型到对象。因为感觉很奇怪,所有方法都返回相同类型的对象。

共有1个答案

步兴德
2023-03-14

不能更改被包围方法的返回类型。JVM的机制不允许这样做(请参见本问题的答案)。

方法的调用者根据原始方法的接口编译他的代码,但是在执行了方法之后,方法返回了一个不同的类型。那该怎么做呢?

一种可能是使用一个接口并返回根据您的建议创建的不同实现,例如:

interface MyReturnType {
  int getStatus();
  Map<String, String> getData();
}

class MethodReturnType implements MyReturnType {
  int getStatus() { throw NotImplementedException(); } 
  // should never be called; every other method in the interface can be implemented in the exact same way


  Map<String, String> getData() { return data; } // I omit the constructor and field decleration here
}

class AdviceReturnType implements MyReturnType {
  int status;
  Map<String, String> data;

  int getStatus() { return status; } 
  Map<String, String> getData() { return data; }
}


public MyReturnType myAdvicedMethod(...) {
  // ...
  return new MethodReturnType(myCalculatedData);
}

public Object aroundAdvice(ProceedingJoinPoint pjp) {
  MyReturnType retVal = (MyReturnType) pjp.proceed();
  // calculate status and stuff
  return new AdviceReturnType(retVal.getData(), caluclatedStatus, ...);
}
 类似资料:
  • 我正在处理一个web服务,它一次加载ApplicationResponse对象n。我想创建一个流,它允许我使用所有这些流,而不必担心分页,因此我(不完整)使用了Java流。 我有一个生成页码的流。我想使用我以前写的函数将这些数字映射到响应流。 问题是,它似乎希望我的arrow函数返回int,而不是我所期望的流。 如何重写此表达式以使映射操作正常工作?

  • 在static_cast、dynamic_cast、reinterpret_cast和const_cast中,只有static_cast能够返回所需类型的对象,而另一种类型只能返回表示的指针或引用。为什么会这样? 例子: 对于dynamic_cast:

  • 我正在尝试调用FlickR API,但由于response.body()返回null而遇到困难。 我不确定它是否与我的JSON/POJO映射相关,但我无法弄清楚当我调用Flickr时如何访问来自改版的响应。我知道我的调用已经成功完成,因为我实际上能够通过日志拦截器查看JSON。 型号: 活动 }

  • 问题内容: 我正在向我的朋友解释OOP。我无法回答这个问题。(我有多可耻? 我只是想逃避,因为OOP描绘了现实世界。在现实世界中,父母可以容纳孩子,但孩子不能容纳父母。OOP也是如此。我知道它很愚蠢。:P 为什么此陈述无效? 因为aChild的成员是aParent成员的超集。那为什么孩子不能容纳父母。 问题答案: 正是因为aChild是aParent功能的超集。你可以写: 因为每只狐狸都是动物。但

  • 我使用的是Spring版本4(Spring data),我想将Object作为JSON返回,我想知道以下代码即使不使用xmlRootElement注释用户类也能工作: 任何机构都可以解释吗?当我需要注释要返回为JSON的对象类时,响应体/响应实体是否自己完成工作?

  • line.FlatMap(WordSutil::GetWords)是方法引用中错误的返回类型: 编码方法: