11

我有一个用 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
    }

如果有人使用“onlyImmediateChildren=true”参数(拼写错误)而不是“onlyImmediateChildren=true”调用此方法,Spring MVC 将忽略输入错误的参数并假设“onlyImmediateChildren”为空。开发人员将获得稍微不正确的结果列表,并且不会注意到错误。此类问题可能普遍存在且难以诊断。我想检查查询字符串中没有错别字的参数以防止此类问题。

更新

可以从查询字符串中提取实际参数列表。然后可以将其与允许的参数列表进行比较。如果我对允许的参数列表进行硬编码,它将复制方法签名。我想知道从方法签名中提取允许的参数列表是否容易(例如通过@RequestParam 注释)?

非常感谢

格言

4

4 回答 4

6

您可以实现自己的HandlerInterceptor。在 preHandle 方法中,您可以获取所有带有 @RequestParameter 注释的 HandlerMethod 参数。这些将是请求中所有允许的参数。

于 2012-04-04T20:31:38.957 回答
1

您可以使用getParameterMap请求的方法来获取Map所有提交的参数,并根据所有允许的参数列表验证键。您应该能够request通过简单地将对象添加到方法签名来获取对象,例如:

public List<MetricType> getMetricTypes(   
    HttpServletRequest request,
    @RequestParam(value = "subject", required = false) Long subjectId,
    ...
) throws Exception {
于 2012-04-04T11:39:34.217 回答
1

Spring 将通过 type 的参数注入 url 字符串中存在的所有查询参数

@RequestParam Map<String,String>在您的控制器方法中(如果存在)。

@RequestMapping(value = "", method = RequestMethod.GET, produces = {"application/json"})
 public HttpEntity<PagedResources<WebProductResource>> findAll(@RequestParam Map<String, String> allRequestParams){
...

}

然后,您可以自己验证地图的键。对于一般的“企业”方式,请在此处查看我的答案:如何检查 spring RestController 中的未知查询参数?

于 2018-01-15T04:31:58.497 回答
1

这是我的一个实现,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)
    }
}
于 2020-06-23T11:51:00.153 回答