Spring - перехватывает ответ от другого компонента обработчиком исключений - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть два @RestController s - (A и B) и зарегистрировано ResponseEntityExceptionHandler.Можно ли (и как это сделать) позвонить с A и получить ответ от B после применения обработчика исключений?

Пример:

  1. Пользовательский отдыхвызов A
  2. A вызов B с getPerson
  3. B сгенерирует исключение NotFound
  4. NotFound обрабатывается обработчиком исключений, преобразуя ResponseEntity и поставив 400 статус
  5. B наконец вернет исключение ResponseEntity
  6. A получает 400 статус из B
  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;
    }

}

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Невозможно вернуть управление контроллеру из обработчика исключений, который вызывается после обработки его метода. Ваш текущий поток выглядит следующим образом call A.addPersons -> invoke B.addPerson -> B throws exception -> exception is propagate to A controller и сохраняется как dispatchException для дальнейшей обработки в DispatcherServlet после обработки метода контроллера (не ResponseEntity со статусом 400) -> исключение обрабатывается 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!");
    }
}
0 голосов
/ 12 сентября 2018

forward аналогичен перенаправлению, но происходит полностью на стороне сервера; контейнер сервлетов направляет тот же запрос на целевой URL; URL не изменится в браузере. весной вы можете сделать это следующим образом и передать атрибут:

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

    @GetMapping("/forward")
    public ModelAndView redirectWithUsingForwardPrefix(ModelMap model) {
        model.addAttribute("attribute", "forward");
        return new ModelAndView("forward:/redirectedUrl", model);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...