Возврат ошибки и сообщения от контроллера или службы Spring - PullRequest
9 голосов
/ 22 апреля 2011

Я перевожу некоторые сервлеты в среду Spring, используя Spring MVC. В настоящее время в каждом сервлете мы аутентифицируем пользователя, и если аутентификация не проходит, мы делаем это:

if (authfailed)
{
  response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
                     "You are not authorized.");
  return;
}

На внешнем интерфейсе находится приложение на основе YUI, и когда возвращается статус ошибки, обратный вызов «fail» отображает диалоговое окно с сообщением об ошибке, приведенным выше.

Я знаю, что в моем контроллере я могу получить объект ответа и вызвать sendError, но разве это лучший способ справиться с этим? sendError также создает исключение IOException, поэтому мне придется это отловить - немного раздражающего кода, который нужно вставить в каждый метод каждого контроллера.

У меня та же проблема с обработкой исключений - у сервлетов есть блоки try-catch, которые вызывают sendError в методе catch. Я знаю, что могу пометить свои обработчики исключений

@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND)

но разве класс обработки исключений не должен присутствовать в каждом классе контроллера?

Наконец, если исключение происходит в службе, вызываемой из контроллера, возникнет ли исключение на контроллере или я должен обработать исключение в службе (таким образом, перенося эти проблемы обработки исключений на уровень службы)?

Это кажется более сложным, чем должно быть, но, как и во многих вещах весной, скорее всего, я не понимаю, что происходит. Все, что я хочу сделать, это отправить статус ошибки и сообщение обратно в ответ!

Спасибо

Пол

1 Ответ

16 голосов
/ 23 апреля 2011

Похоже, что у вас есть большинство ответов на ваш вопрос:)

Чтобы повторить,

У контроллера вот так

@RequestMapping("/test") 
public String verifyAuth(HttpServletRequest request) throws NotFoundException {
    String id = request.getParameter("id");

    if (id == null) 
        throw new NotFoundException("Id not found in the request");

    return "success";
}

Объявите класс исключений в NotFoundException.java,

@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Id Not Found")
public class NotFoundException extends Exception {

    public NotFoundException(String msg) {
        super(msg);
    }
}

Этот класс исключений не обязательно должен быть каждым классом контроллера. Объявите его как открытый класс и импортируйте его в каждый требуемый контроллер.

Это один из способов сделать это. Если вам нравится стиль, отличный от Spring, объявите HttpServletResponse в аргументах каждого контроллера и выполните

@RequestMapping("/test") 
public String verifyAuth(HttpServletRequest request, HttpServletResponse response) {
   ...
   try {
    response.sendError(..)
   catch(..) {}
}

Или вы можете использовать представления для отображения сообщения об ошибке,

@RequestMapping("/test") 
public String verifyAuth(HttpServletRequest request, Map<String, Object> map){
    String id = request.getParameter("id");

    if (id == null)  {
        map.put("status", HttpStatus.NOTFOUND);
        map.put("reason", "Id Not Found");

        return "error"
     }
      return "success";
}

Убедитесь, что ваш viewResolver настроен правильно, и вы можете сказать, что в файле error.jsp для получения строки ошибки.

<body>
${status} ${reason}
</body>

Определите error.jsp с хорошим css для всех возможных ошибок. Это не единственные способы. С весной у тебя есть свобода делать что угодно. Я видел несколько ppl рендеринга объекта json для сообщения об ошибке.

Ответ на ваш другой вопрос о том, произошла ли ошибка в службе, вызываемой контроллером, зависит от вашего сценария. Например, вы пытаетесь прочитать хранилище пользователя, если возникает ошибка недоступности хранилища пользователя, я бы обработал сам себя для чтения из другого хранилища пользователей реплики, если оно доступно, и если я обнаружил, что пользователь не существует, я бы оставил исключение для контроллер бросить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...