복붙노트

[SPRING] Spring MVC Rest Service Controller는 오류 처리가 올바르게 완료 되었습니까?

SPRING

Spring MVC Rest Service Controller는 오류 처리가 올바르게 완료 되었습니까?

REST 서비스로 제공 될 스프링 컨트롤러를 올바르게 구현하는 방법을 궁금해했다. 특히 인터페이스를 최대한 RESTful로 만들고 싶습니다. 또한 내 고객이 그에 따라 행동 할 수 있도록 HTTP 오류 코드를 사용하고 싶습니다.

내 메서드를 구현하는 방법을 궁금 해서요, 그래서 그들은 모두 (응답 본문) 또는 HTTP 오류 코드를 던져서 잘 작동하는 경우 JSON 반환합니다 그것은 왜 작동하지 않았다는 사용자 지정 이유 (어쩌면 DAO 또는 데이터베이스). 그러나 어느 것이 옳은 것인지 잘 모르겠습니다. String을 반환하고 값을 추가하여 Model로 반환하거나 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;
    }
}

코드가 "올바른 것"이 아니라는 것을 알지만, 필요한 방식으로 만드는 법을 알 수는 없습니다. 어쩌면 일부 경험이 도움이 될 것입니다. 이미 지원을위한 Thx

해결법

  1. ==============================

    1.Rest Controller 내에서 @ExceptionHandler 주석이 달린 메토로 예외를 잡을 수도 있습니다.

    Rest Controller 내에서 @ExceptionHandler 주석이 달린 메토로 예외를 잡을 수도 있습니다.

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

    이것은 실제 컨트롤러 / 비즈니스 로직을보다 깨끗하게 만듭니다.

  2. ==============================

    2.첫째, JSON을 반환 할 때 항상 객체를 반환해야한다고 생각합니다. 무언가가 끔찍하게 잘못 될 때조차도.

    첫째, 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을 사용하면 되겠지만 반환 할 객체를 정의하는 리소스 클래스를 작성하는 것이 좋습니다. 그들은 유지하기가 더 쉬울 것입니다. 지도는 구조를 제공하지 않지만 구조는 REST 서비스를 만들 때 매우 중요한 부분입니다.

    원시 예외 메시지가 포함 된 리소스를 반환해야한다고 생각하지 않습니다. 누구도보고 싶지 않은 정보가 유출 될 수 있습니다.

  3. ==============================

    3.@ExceptionHandler를 @ControllerAdvice와 함께 사용하면이 링크를 확인할 수 있습니다.

    @ExceptionHandler를 @ControllerAdvice와 함께 사용하면이 링크를 확인할 수 있습니다.

  4. ==============================

    4.ResponseEntity 클래스를 사용하여 http 상태 코드로 오류를 악용하십시오.

    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. ==============================

    5.@Bart가 "ErrorResource"객체를 보내야한다고 말한 것처럼 StackTrace를 사용하여 전체 Exception을 클라이언트로 전송하기를 원한다면.

    @Bart가 "ErrorResource"객체를 보내야한다고 말한 것처럼 StackTrace를 사용하여 전체 Exception을 클라이언트로 전송하기를 원한다면.

    라이브러리에는 기성품이 있습니다.

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

    이를 프로젝트에 추가 한 다음 콩에 "@ControllerAdvice"클래스를 추가하십시오. 프로젝트 위키에 설명되어 있습니다.

    그 오류를 멋지게 처리해야합니다!

  6. from https://stackoverflow.com/questions/16295184/spring-mvc-rest-service-controller-with-error-handling-done-right by cc-by-sa and MIT license