簡體   English   中英

Spring-異常處理程序攔截來自另一個bean的響應

[英]Spring - Intercept response from another bean by exception handler

我有兩個@RestController s-(A和B)和注冊的ResponseEntityExceptionHandler 應用異常處理程序后,是否有可能(以及如何執行)從A調用並從B獲得響應?

例:

  1. 用戶休息電話A
  2. AgetPerson調用B
  3. B拋出NotFound異常
  4. NotFound由異常處理程序處理,轉換ResponseEntity並放置400狀態
  5. B終於返回異常ResponseEntity
  6. AB獲得400狀態
  7. A可以得到這個400並用它做點什么

簡單的@Autowired無法正常工作。

片段:

A:

@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;
    }

}

轉發就像重定向,但完全發生在服務器端; Servlet容器將相同的請求轉發到目標URL; 該網址在瀏覽器中不會更改。 在春季,您可以這樣做,並且可以傳遞attribute:

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

    @GetMapping("/forward")
    public ModelAndView redirectWithUsingForwardPrefix(ModelMap model) {
        model.addAttribute("attribute", "forward");
        return new ModelAndView("forward:/redirectedUrl", model);
    }
}

無法從異常處理程序中將控制權返回給控制器,該異常處理程序在處理其方法后將被調用。 您當前的流程如下所示: call A.addPersons > invoke B.addPerson > B throws exception -> exception is propagate to A controller並在處理控制器方法(狀態為400的ResponseEntity)后另存為dispatchException以便在DispatcherServlet中進一步處理->異常由MyExceptionHandler處理。 您無法從這個地方回到控制器。

我不確定要在控制器中使用此異常來做什么,但是解決方案可能如下所示:

@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!");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM