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

Spring-通过异常处理程序拦截来自另一个bean的响应

时恩
2023-03-14

我有两个@一来控制器s-(A和B)并注册了响应EntityExceptionHandler。是否可以(以及如何做到)从A调用并在应用异常处理程序后从B获得响应?

例子:

  1. 用户Rest呼叫A
  2. A使用getPerson
  3. 调用
  4. B引发异常未找到
  5. NotFound由异常处理程序处理,转换ResponseEntity并放置400状态
  6. B最终返回异常响应实体
  7. AB
  8. 获取400状态
  9. 一个可以得到这个400并用它做点什么

简单的< code>@Autowired不起作用。

片段:

答:

@RestController
@RequestMapping("/v1")
public class A {

    private final B b;

    @Autowired
    public A(B b) {
        this.b = b;
    }

    @PostMapping(
        value = "persons",
        consumes = "application/json",
        produces = "application/json")
    public ResponseEntity<List<StatusResponse<Person>>> addPersons(final List<Person> persons) {
        final List<StatusResponse<Person>> multiResponse = new ArrayList<>();
        for(final Person p: persons) {
            final ResponseEntity<Person> response = b.addPerson(person);
            multiResponse.add(new StatusResponse<>(
                response.getStatusCode(), response.getMessage(), response.getBody()
            ));
        }
        return ResponseEntity.status(HttpStatus.MULTI_STATUS).body(multiResponse);
    }

}

B:

@RestController
@RequestMapping("/v1")
public class B {

    @PostMapping(
        value = "person",
        consumes = "application/json",
        produces = "application/json")
    public ResponseEntity<Person> addPerson(final Person person) {
        accessService.checkAccess();
        return ResponseEntity.status(201).body(
            logicService.addPerson(person)
        );
    }

}

处理程序

@ControllerAdvice
public final class MyExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MyException.class)
    protected ResponseEntity<Object> handleApiException(final MyException exception, final WebRequest webRequest) {
        //logic
        return afterLogic;
    }

}

共有2个答案

戚均
2023-03-14

转发类似于重定向,但完全发生在服务器端;Servlet 容器将相同的请求转发到目标 URL;网址不会在浏览器中更改。在Spring你可以这样做,你可以传递属性:

@Controller
@RequestMapping("/")
public class YourController {

    @GetMapping("/forward")
    public ModelAndView redirectWithUsingForwardPrefix(ModelMap model) {
        model.addAttribute("attribute", "forward");
        return new ModelAndView("forward:/redirectedUrl", model);
    }
}
滕无尘
2023-03-14

不可能从异常处理程序将控制返回给控制器,异常处理程序是在处理其方法后调用的。您当前的流程看起来像这个调用A.add-

我不确定您想在控制器中处理此异常时做什么,但解决方案可能如下所示:

@RestController
@RequestMapping("/resources")
public class AController {

    private BService service;

    @Autowired
    public AController(BService service) {
        this.service = service;
    }

    @RequestMapping("/test")
    public ResponseEntity<String> test() {
        ResponseEntity<String> result = service.test();
        if (result.hasBody()) {
            //doSomething
        }

        return result; //or list like you did
    }
}

@Service
public class BService {

    public ResponseEntity<String> test() {
        try {
            return ResponseEntity.status(201).body(getResponse()); //this always throws exception. It's just for purpose of example
        } catch (CustomException ex) {
            return ResponseEntity.status(400).build();
        }

    }

    private String getResponse() {
        throw new CustomException("Not OK!");
    }
}
 类似资料:
  • 我试图执行一些适用于代码中所有的通用逻辑。我知道我可以编写一个来拦截快乐路径。但是,我想连接到异常处理生命周期中,以便在呈现错误响应之前执行一些常见的逻辑,比如日志记录。 在Spring Boot/Spring MVC中有这样做的方法吗?如果可能的话,我希望避免为此编写servlet过滤器。

  • 我知道我们可以将不同的url映射到不同的拦截器,或者我们也可以将多个url映射到单个拦截器。我只是想知道我们是否也有排除选项。例如,如果我在应用程序中有50个url映射,除了1个映射之外,我想为所有这些调用拦截器,而不是为49个映射编写配置,那么我可以只提到*和一个排除到第50个url吗?

  • 我的项目是基于spring mvc的,我写了一个拦截器来拦截请求,我想从请求中获取参数,下面是我的代码: 但现在它抛出了一个异常: 出现例外的原因是什么?

  • 我最近几天在玩Spring拦截器,想通过拦截器捕捉和处理特定的请求。我要做的是在每个请求被特定的控制器处理之前拦截它,检查请求是否包含特定的参数。如果是,做一些事情,然后将这些事情签名到映射请求的控制器。 最后,我设法做到了这一点,但当我使用不同的参数值一次执行多个请求时,只有来自上一个请求的参数值被分配给每个控制器处理程序,甚至每个控制器都应该有包含在请求中的参数。 示例(同时执行): http

  • 我正在用Spring Boot开发一个rest应用程序。此应用程序有一个自定义筛选器,只允许在某些请求下访问。如果用户需要特定的资源,筛选器将抛出异常。如何在全局级别处理此筛选器中生成的所有异常? 我尝试了注释,但不起作用。

  • 我能以某种方式截获来自应用程序的绝对所有流量吗?我应该做什么来做到这一点?提前谢谢你)