Подтвердить что ты не робот

Spring MVC Rest Service Controller с обработкой ошибок, выполненной правильно?

Мне было интересно, как правильно реализовать контроллер Spring, который должен служить службой REST. Особенно хочу попробовать сделать интерфейс RESTful максимально возможным. Также я хотел бы использовать коды ошибок HTTP, чтобы мои клиенты могли действовать соответственно.

Мне было интересно, как реализовать мои Методы, поэтому они возвращают JSON, если все работает нормально (в теле ответа) или бросает код ошибки http, а также неподдельную причину, почему он не работал (может быть, ошибки, пришедшие из DAO или базы данных). Однако я не уверен, какой из них правильный? вернуть строку и добавить значения для возврата в модель или вернуть HashMap и поместить туда мои вещи? или вернуть объекты напрямую? но тогда что, если произошла ошибка, и я не могу вернуть упомянутый класс? вместо этого возвращает null? Я размещаю 2-3 способа сделать это, что я мог себе представить:

@RequestMapping(value="/addUser", method= RequestMethod.POST)
public String addUser(@RequestBody User user, HttpServletResponse response, Model model) throws Exception{

    try{
        userService.addUser(user);
        model.addAttribute("user", userService.getUser(user.getUsername(), user.getPassword()));
        return "user";
    }catch(Exception e){
        model.addAttribute("error", e.toString());
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
        return "error";
    }
}

Или, скорее, так:

@RequestMapping(value="/addUser", method= RequestMethod.POST)
public @ResponseBody Map addUser(@RequestBody User user, HttpServletResponse response){
    Map map = new HashMap();
    try{
        userService.addUser(user);
        map.put("success", true);
        map.put("username", user.getUsername());
    }catch (KeyAlreadyExistsException e){
        map.put("success", false);
        map.put("Error", e.toString());
        response.sendError(HttpServletResponse.SC_FORBIDDEN, e.toString());
    }catch(Exception e){
        map.put("success", false);
        map.put("Error", e.toString());
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
    }
    finally {
        return map;
    }
}

Я понимаю, что код не "прав", но я не могу понять, как сделать его таким, каким он должен быть. Может быть, некоторые впечатления помогут? спасибо для поддержки уже

4b9b3361

Ответ 1

Вы также можете воспользоваться своими исключениями с помощью @ExceptionHandler аннотированных меток в вашем контроллере отдыха.

@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public String handleException(Exception e) {
    return "return error object instead";
}

это сделает ваш acutal контроллер/бизнес-логику более чистым.

Ответ 2

Во-первых, я думаю, вы всегда должны возвращать объект при возврате JSON. Даже когда что-то идет ужасно неправильно.

Когда что-то пойдет не так, вы просто установите response.setStatus() и вернете ресурс, описывающий ошибку.

public class ErrorResource implements Resource {
    private final int status;
    private final String message;

    public ErrorResource(int s, String m) {
        status = s;
        message = m;
    }

    public int getStatus() {
        return status;
    }

    public String getMessage() {
        return message;
    }
}

Ресурс сериализуется, и результат будет

{"status":500, "message":"Yay!"}

Использование Map будет работать, но я хотел бы посоветовать вам написать некоторые классы ресурсов, которые определяют возвращаемый объект. Их было бы легче поддерживать. Maps не предлагают никакой структуры, в то время как структура является очень важной частью при создании службы REST.

Я не думаю, что вы должны вернуть ресурс с встроенным необработанным сообщением об исключении. Это может потенциально утечка информации, которую вы не хотите видеть.

Ответ 3

вы можете использовать @ExceptionHandler с @ControllerAdvice проверить эту ссылку

Ответ 4

используйте класс ResponseEntity для использования ошибки с кодом состояния http.

Вы можете попробовать следующий код:

@RequestMapping(value = "/profile", method = RequestMethod.GET) 
@ResponseBody @ResponseStatus(value = HttpStatus.OK) 

public ResponseEntity<UserVO> getUserProfile() 
{ 
   string userName = getUserAuthentication().getName(); 
   if (StringUtils.isEmpty(userName)) RestUtil.defaultJsonResponse(""); 
   User user = userService.getUserByUserNameWithCounters(userName); 
   return RestUtil.getJsonResponse(new UserVO(user)); 
}

Ответ 5

Если вы хотите, чтобы все ваше исключение с помощью stackTrace было передано по отношению к вашему клиенту, поскольку @Bart сказал, что вы должны отправить объект ErrorResource.

У библиотеки есть своя версия:

<dependency>
  <groupId>com.github.zg2pro</groupId>
  <artifactId>spring-rest-basis</artifactId>
  <version>0.2</version>
</dependency>

добавьте его в свой проект, а затем просто добавьте класс @ControllerAdvice к вашему beans, как это объясняется в вики проекта.

Это должно хорошо справляться с вашими ошибками!