给出一个Spring-MVC控制器方法:
@RequestMapping(value = "/method")
public void method(ParamModel params) { /*...*/ }
使用模型类:
public class ParamModel { public int param1; }
以下两个结果符合预期/期望:
param1=1
:method
成功完成。param1=blah
:JBWEB000120: The request sent by the client was syntactically incorrect.
...然而
nonexistentparam=1
),则没有错误。如果请求包含任何不属于此API的参数,是否有办法确保请求已经过验证和拒绝?
答案 0 :(得分:1)
您可以使用过滤器检查无效参数
的的web.xml 强> 的
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.mypackage.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
MyFilter Class
import javax.servlet.Filter;
public class MyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String requestUrl = request.getParameter("param1");
//here I am considering 'param1=1' as valid request rest of all are invalid
if(!requestUrl.equals("1")) {
logger.info("Invalid Request");
//for invalid request redirect to error or login page
response.sendRedirect("/error"");
} else {
logger.info("Valid Request");
}
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
希望这能解决您的问题
答案 1 :(得分:0)
一个很好的做法是Bean-Validation(JSR-303)。这是Document
保持简单,你需要在你的spring配置中使用它:
<mvc:annotation-driven />
您可以在代码中使用此功能:
@RequestMapping(value = "/method")
public void method(@Valid ParamModel params, BindingResult result) {
if(result.hasErrors()) {...}
else {...}
}
public class ParamModel {
@SomeAnnotation // details see document
private int param1;
}
答案 2 :(得分:0)
Spring的@RequestMapping采用“params”参数。
文档:
映射请求的参数,缩小主映射。
任何环境的格式相同:一系列“myParam = myValue”样式 表达式,只有在每个这样的参数都被映射时才会映射 发现有给定的价值。使用表达式可以取消表达式 “!=”运算符,如“myParam!= myValue”。 “myParam”风格表达 也支持,这些参数必须存在于 请求(允许有任何价值)。最后,“!myParam”风格 表达式表明不应该指定参数 出现在请求中。
另一种可能性是使用PathVariable(始终需要)或RequestParam参数 required = true 。
<强>更新强>
您可以通过继承RequestMappingHandlerMapping并覆盖getCustomMethodCondition / getCustomTypeCondition来创建自己的请求映射条件。
然而,不能使用XML配置<mvc:annotation-driven/>
,因为它也声明了这个Bean,你最终会得到2个处理程序映射。
有关详细信息,请查看Adding custom RequestCondition's in Spring mvc 3.1。
答案 3 :(得分:0)
最明显,最无聊和非弹性的选择是使用:
@RequestParam Map<String,String> allRequestParams
...并自行检查参数列表。它当然要求您解析(到整数等)并手动验证值,而不是使用DTO和/或javax.validation注释。
完整示例(需要将InvalidParamsException映射到状态代码):
@GetMapping("/my_strict_api")
public void myStrictApi(@RequestParam Map<String,String> allRequestParams) {
Set<String> allowed = new HashSet<>(Arrays.asList("cat", "dog"));
if (!allowed.containsAll(allRequestParams.keySet())) {
throw new InvalidParamsException("We only accept: " + allowed.toString());
}
// You should also validate the parameter values before using them
}
答案 4 :(得分:0)
有一种方法可以覆盖控制器请求方法调用:
@Bean
public WebMvcRegistrations mvcRegistrations() {
return new WebMvcRegistrationsAdapter() {
@Override
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
return new RequestMappingHandlerAdapter() {
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
@Override
protected ServletInvocableHandlerMethod createInvocableHandlerMethod(HandlerMethod handlerMethod) {
return new ServletInvocableHandlerMethod(handlerMethod) {
Set<String> boundParametersNames = Stream.of(getMethodParameters())
.map(methodParameter -> {
methodParameter.initParameterNameDiscovery(parameterNameDiscoverer);
return methodParameter.getParameterName();
})
.collect(Collectors.toSet());
@Override
public Object invokeForRequest(NativeWebRequest request,
ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
for (Iterator<String> iterator = request.getParameterNames(); iterator.hasNext(); ) {
String parameterName = iterator.next();
if (!boundParametersNames.contains(parameterName)) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
}
return super.invokeForRequest(request, mavContainer, providedArgs);
}
};
}
};
}
};
}
在InvocableHandlerMethod中,可以轻松访问和验证请求参数和方法参数。