I have a web service written in Spring MVC. It can be used by 3rd party developers. Our methods have a lot of optional parameters (passed in the query string).
I want to make sure that all the query string parameters are spelled correctly and there is no typos. Is there an easy way to do it? Method signature example:
@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
}
If somebody calls this method with "onlyImediateChildren=true" parameter (a typo) instead of "onlyImmediateChildren=true", Spring MVC will ignore the typoed parameter and will assume "onlyImmediateChildren" is null. Developer will get slightly incorrect list of results and will not notice the error. Such issues could be widespread and difficult to diagnose. I want to check there is no typoed params in query string to prevent such issues.
UPDATE
It is possible to extract the list of actual parameters from the query string. Then it could be compared with the list of the allowed parameters. If I hardcode the allowed parameter list, it will duplicate the method signature. I wonder if it is easy to extract a list of allowed parameters from the method signature (e.g. by @RequestParam annotation)?
Many thanks
Maxim
You could implement your own HandlerInterceptor. In preHandle method you can obtain all HandlerMethod's parameters annotated with @RequestParameter. These will be all allowed parameters in request.
Here is my implementation of an HandlerInterceptor
which will only accept the parameters which are explicitely defined by a parameter annotation:
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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With