2014-09-12 3 views
5

RESTful 서비스에서 잘못된 매개 변수를 처리하는 적절한 방법은 무엇입니까? 잘못된 데이터 형식을 보내면 끝 점이 400 개가됩니다.REST 잘못된 매개 변수 처리

@ResponseBody 
@RequestMapping(produces = "application/json", method = RequestMethod.GET, value="/v1/test") 
public MyResponse getSomething(@RequestParam BigDecimal bd) { 
    MyResponse r = new MyResponse(); 
    r.setBd(bd); 
    return r; 
} 
응답이 내가 원하는 응답 코드, 상태 및 어떤 다른와 JSON을 반환 것으로, 최종 사용자가, 말하자면, 대신을 BigDecimal의 캐릭터를 통과한다면 정말 좋을 것

그것을 포함하는 것이 아니라 단지 400입니다. 이것을 할 수있는 방법이 있습니까?

업데이트 : 처음에는 모든 매개 변수를 래핑 한 다음 해당 래퍼 클래스에 올바른 유형인지 확인했습니다. 이것은 약간 바보 같다. 클래스 패스에 추가 할 수있는 validator가 없습니까?

또한 독자적으로 만들 수있는 Bean 유형을 사용하여이 작업을 매우 쉽게 처리 할 수 ​​있지만 BigDecimal과 같은 표준 유형은 무엇입니까?

UPDATE-2 :이 업데이트는 @ExceptionHandler를 사용하는 대답을 해결합니다.

TestController.java

import java.math.BigDecimal; 
import javax.servlet.http.HttpServletRequest; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.ServletRequestBindingException; 
import org.springframework.web.bind.annotation.ExceptionHandler; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.ResponseBody; 

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

    //this is where correct input from user is passed, no binding errors 
    @RequestMapping(produces = "application/json", method = RequestMethod.GET, value="/v1/test") 
    public 
    @ResponseBody 
    MyResponse getSomething(@RequestParam BigDecimal bd) { 
     MyResponse r = new MyResponse(); 
     r.setBd(bd); 
     return r; 
    } 

    //this will handle situation when you except number and user passess string (A123.00 for example) 
    @ExceptionHandler(ServletRequestBindingException.class) 
    public @ResponseBody MyErrorResponse handleMyException(Exception exception, HttpServletRequest request) { 

     MyErrorResponse r = new MyErrorResponse(); 
     r.setEexception(exception); 

     return r; 
    } 


} 

TestUnitTest.java

public class TestUnitTest { 

protected MockMvc mockMvc; 

@Autowired 
protected WebApplicationContext wac; 

@Before 
public void setup() { 
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); 
} 


@Test 
public void test() throws Exception { 
    String url = "/v1/test?bd=a123.00"; 

    log.info("Testing Endpoint::: " + url); 

    MvcResult result = mockMvc.perform(get(url)) 
         .andExpect(status().isOk()) 
         .andReturn(); 

    log.info("RESPONSE::: " + result.getResponse().getContentAsString()); 
} 

} 

MyResponse.java

import java.math.BigDecimal; 

public class MyResponse { 

    private BigDecimal bd; 

    public BigDecimal getBd() { 
     return bd; 
    } 

    public void setBd(BigDecimal bd) { 
     this.bd = bd; 
    } 

} 
이 같은 표준 @RequestMapping 주석과 함께

MyErrorResponse.java

public class MyErrorResponse { 

    private Exception exception; 

    public Exception getException() { 
     return exception; 
    } 

    public void setEexception(Exception e) { 
     this.exception = e; 
    } 

} 

답변

3

사용 봄 @ExceptionHandler는 :

//this is where correct input from user is passed, no binding errors 
@RequestMapping(produces = "application/json", method = RequestMethod.GET, value="/v1/test") 
public 
@ResponseBody 
MyResponse getSomething(@RequestParam BigDecimal bd) { 
    MyResponse r = new MyResponse(); 
    r.setBd(bd); 
    return r; 
} 

//this will handle situation when there's exception during binding, for example you except number and user passess string (A123.00 for example) 
@ExceptionHandler(TypeMismatchException.class) 
public 
@ResponseBody 
MyErrorResponse handleMyException(Exception exception, HttpServletRequest request) { 
    //.... 
} 

TypeMismatchException 빈 속성을 설정하려고 할 때 발생 일반적인 예외입니다. 그것은 매우 유연

@ExceptionHandler(TypeMismatchException.class) 
public 
@ResponseBody 
String typeMismatchExpcetionHandler(Exception exception, HttpServletRequest request) { 
    return "type mismatch"; 
} 

@ExceptionHandler(MissingServletRequestParameterException.class) 
public 
@ResponseBody 
String missingParameterExceptionHandler(Exception exception, HttpServletRequest request) { 
    return "missing param"; 
} 

@ExceptionHandler(Exception.class) 
public 
@ResponseBody 
String generalExceptionHandler(Exception exception, HttpServletRequest request) { 
    return "general exception"; 
} 

를, 서명에 많은 매개 변수를 허용하고 당신이 어떤 객체를 반환 할 수 있습니다 @ResponseBody으로 객체 Annotation Type ExceptionHandler

을 반환 : 당신은 더 많은 코드를 일반화하고, 예를 들어, 몇 가지 방법으로 모든 바인딩 예외를 잡을 수 있습니다 JSON으로 직렬화 할 수 있습니다. 클래스 패스에 jackson 라이브러리 만 있으면 좋겠지 만 이미 알고 있다고 가정합니다.

+0

전달할 예외가 있으면 좋을 것입니다. 내가 믿는 나의 경우는 다르다. RESTful 서비스에 전달 된 매개 변수의 유효성을 검사하고 싶습니다. 그래도 이걸 쓸 수 있다고 생각한다면 예를 들어 주시겠습니까? 고맙습니다! – Matt

+0

나는 당신을 올바르게 이해하는지 잘 모르겠습니다. 따라서 사용자가 아무 것도 전달하지 않고 유효성을 검사하도록 허용 하시겠습니까? '@ ExceptionHandler'는 바인딩 매개 변수 (예 : 숫자와 문자열이 전달되는 것을 제외하고) 중에 던져진 예외가있을 때 호출됩니다.'@ RequestMapping'이 나오면 바인딩이 정확하다는 것을 의미합니다. 좀 더 설명해 줄 수 있니? – kamil

+0

위의 예에서 나는 메서드가 BigDecimal을 취해야합니다. 그러나 최종 사용자가 A123을 통과하면.00이면 400을 반환합니다 (실수는 123.00 앞에 'A'가 있음). 나는 Sotirios가 제안하고있는 것처럼 당신이 데이터 타입을 포장하지 않는다면 당신이 이것을 할 수 없다는 결론에 이르고있다. – Matt