我有一个用Spring MVC编写的Web服务。它可以被第三方开发人员使用。 我们的方法有很多可选参数(在查询字符串中传递)。
我想确保所有查询字符串参数拼写正确并且没有拼写错误。 有一个简单的方法吗?方法签名示例:
@RequestMapping(value = {"/filter"}, method = RequestMethod.GET)
@ResponseBody
public List<MetricType> getMetricTypes(
@RequestParam(value = "subject", required = false) Long subjectId,
@RequestParam(value = "area", required = false) Long areaId,
@RequestParam(value = "onlyImmediateChildren", required = false) Boolean onlyImmediateChildren,
@RequestParam(value = "componentGroup", required = false) Long componentGroupId
) throws Exception
{
//Some code
}
如果某人使用“onlyImediateChildren = true”参数(拼写错误)而不是“onlyImmediateChildren = true”调用此方法,则Spring MVC将忽略拼写错误的参数,并假设“onlyImmediateChildren”为空。开发人员会得到稍微不正确的结果列表,并且不会注意到错误。这些问题可能很普遍,难以诊断。我想检查一下查询字符串中是否存在拼写错误,以防止出现此类问题。
更新
可以从查询字符串中提取实际参数列表。然后可以将其与允许参数列表进行比较。如果我对允许的参数列表进行硬编码,它将复制方法签名。我想知道从方法签名中提取允许参数列表是否容易(例如通过@RequestParam注释)?
非常感谢
马克西姆
答案 0 :(得分:4)
您可以实施自己的HandlerInterceptor。在preHandle方法中,您可以获取使用@RequestParameter注释的所有HandlerMethod参数。这些将是请求中允许的所有参数。
答案 1 :(得分:1)
您可以使用请求的getParameterMap
方法获取所有提交参数的Map
,并根据所有允许参数列表验证密钥。您只需将其添加到方法签名即可获得request
对象,例如:
public List<MetricType> getMetricTypes(
HttpServletRequest request,
@RequestParam(value = "subject", required = false) Long subjectId,
...
) throws Exception {
答案 2 :(得分:1)
Spring将通过类型
的参数注入url字符串中存在的所有查询参数 控制器方法中的 @RequestParam Map<String,String>
(如果存在)。
@RequestMapping(value = "", method = RequestMethod.GET, produces = {"application/json"})
public HttpEntity<PagedResources<WebProductResource>> findAll(@RequestParam Map<String, String> allRequestParams){
...
}
然后,您可以自己验证地图的键。对于通常采用“企业”的方式,请在此处查看我的答案:How to check spring RestController for unknown query params?
答案 3 :(得分:0)
这是我对HandlerInterceptor
的实现,它将仅接受由参数注释明确定义的参数:
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.method.HandlerMethod
import org.springframework.web.servlet.HandlerInterceptor
/**
* Interceptor which assures that only expected [RequestParam]s are send.
*/
@Component
class UnexpectedParameterHandler : HandlerInterceptor {
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
if (handler is HandlerMethod) {
val queryParams = request.parameterNames.toList()
val expectedParams = handler.methodParameters
.map { methodParameter ->
val requestParamName = methodParameter.getParameterAnnotation(RequestParam::class.java)?.name
val parameterName = methodParameter.parameter.name
requestParamName ?: parameterName
}
val unknownParameters = queryParams.minus(expectedParams)
if (unknownParameters.isNotEmpty()) {
response.writer.write("unexpected parameter $unknownParameters")
response.status = HttpStatus.BAD_REQUEST.value()
return false
}
}
return super.preHandle(request, response, handler)
}
}