我使用spring 4.2创建了一些restfull webservices。
但我们意识到,当用户输错了其中一个非强制性@RequestParam
时,我们不会得到他传递的参数未知的错误。
就像我们有@RequestParam(required=false, value="valueA")
字符串值A一样,在通话中他使用'?valuueA = AA' - >我们想要一个错误。
但我似乎没有办法做到这一点,价值被忽略,用户也没有意识到这一点。
答案 0 :(得分:3)
一种可能的解决方案是创建HandlerInterceptor
的实现,该实现将验证传递给处理程序方法的所有请求参数是否在其@RequestParam
带注释的参数中声明。
但是你应该考虑这种解决方案的缺点。在某些情况下,您可能希望允许传入某些参数,而不是将其声明为请求参数。例如,如果您有GET /foo?page=1&offset=0
之类的请求,并且具有以下签名的处理程序:
@RequestMapping
public List<Foo> listFoos(PagingParams page);
和PagingParams
是一个包含page
和offset
属性的类,通常会从请求参数映射。实现您想要的解决方案会干扰Spring MVC的功能。
话虽如此,这是我想到的一个示例实现:
public class UndeclaredParamsHandlerInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
checkParams(request, getDeclaredRequestParams(handlerMethod));
}
return true;
}
private void checkParams(HttpServletRequest request, Set<String> allowedParams) {
request.getParameterMap().entrySet().forEach(entry -> {
String param = entry.getKey();
if (!allowedParams.contains(param)) {
throw new UndeclaredRequestParamException(param, allowedParams);
}
});
}
private Set<String> getDeclaredRequestParams(HandlerMethod handlerMethod) {
Set<String> declaredRequestParams = new HashSet<>();
MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
for (MethodParameter methodParameter : methodParameters) {
if (methodParameter.hasParameterAnnotation(RequestParam.class)) {
RequestParam requestParam = methodParameter.getParameterAnnotation(RequestParam.class);
if (StringUtils.hasText(requestParam.value())) {
declaredRequestParams.add(requestParam.value());
} else {
methodParameter.initParameterNameDiscovery(parameterNameDiscoverer);
declaredRequestParams.add(methodParameter.getParameterName());
}
}
}
return declaredRequestParams;
}
}
基本上这将做我上面描述的。然后,您可以为它抛出的异常添加异常处理程序,并将其转换为HTTP 400响应。我在Github上添加了更多完整的示例,其中包括通过注释为各个处理程序方法选择性地启用此行为的方法。