在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;
}
这将是非常好的,如果最终用户都通过,比方说,一个字符串,而不是一个BigDecimal,该响应将返回一个JSON的响应代码,状态,和其他任何我想它包含,而不仅仅是400.有没有办法做到这一点?
更新:我最初的想法是包装每个参数,然后检查它是否是包装类中的正确类型。这似乎有点愚蠢。是不是有一个验证程序,我可以添加到类路径,可以识别这样的事情?
另外,有一种方法可以很容易地用我自己创建的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;
}
}
MyErrorResponse.java
public class MyErrorResponse {
private Exception exception;
public Exception getException() {
return exception;
}
public void setEexception(Exception e) {
this.exception = e;
}
}
如果我有一个例外来传递它,这将会很棒。我认为我的情况有所不同。我希望能够验证传递给RESTful服务的参数。如果你相信我仍然可以使用这个,你会介意举个例子吗?谢谢! – Matt 2014-09-12 19:52:31
我不确定我是否正确理解你。所以你想让用户传递任何东西然后验证它?例如在绑定参数期间(除了传递数字和字符串等)时抛出异常时会调用@ExceptionHandler,当你到达@ @ RequestMapping时,这意味着绑定是正确的,你可以验证。你能解释一点吗? – kamil 2014-09-12 19:59:27
在上面的例子中,该方法应该采用BigDecimal。但是,如果最终用户通过A123。00,它返回一个400(错误是在123.00前有一个'A')。我得出的结论是,你不能这样做,除非你包装数据类型,因为Sotirios建议...... – Matt 2014-09-12 20:19:16