Spring REST Controllers, get unmapped query params - java

Using Spring 4 to create REST controllers, I would like to return warnings in responses of my controllers if clients used unexpected query parameters.
There is a way to get all query parameters (http://stackoverflow.com/questions/7312436), but what I would like is for Spring to provide all query parameters that have not been been mapped to method params by Spring already.
Then I would decide how to treat them, e.g. ignore a some whitelisted query params that have meaning for the client or intermediates, return error when the old name of a parameter was used, return a warning in the response for all other query parameters such that human users can see if their assumption about the query param name was wrong.
So is there an easy way to get all query params from the request that have not been defined using #RequestParam()?

No possibility forthcoming, I opened a ticket:
https://jira.spring.io/browse/SPR-14019

Related

SpringMVC - Naming strategy for #RequestParam

I would like all my APIs to use lower-case request parameters, but I would still like to use camel-case in my Java code.
For example, consider the following code:
#GetMapping("/ping")
public String ping(
String responseMessage)
{
return "PONG " + responseMessage;
}
To contact this endpoint and supply a response message, I would have to call: localhost:8080/ping?responseMessage=Hello. However, I would like spring to automatically bind the variable name responseMessage to a request parameter named responsemessage. I specifically do not want to manually write #RequestParam(name="responsemessage") in my controller, but rather configure a global naming strategy for request parameters. Is this possible?
There are a couple of other threads on SO that talks about making the request parameters or url mappings case-insensitive:
RequestParam value in spring MVC to be case insensitive
Is there any way we make PathVariable name case insensitive in Spring?
Spring mvc. case insensitive get parameters mapping
Making a request parameter binding case insensitive
However, the answers in these questions strikes me as quite hacky or requires manual codeing. Is there no simple setting for the behaviour I am after? I know this is possible when using JSON bodies, by configuring the Jackson propertyNamingStrategy. Is there an equivalent for request parameters?

Having #ModelAttribute in links when using Spring HATEOAS

I'm building urls to my controller methods using tools that Spring HATEOAS provides. The problem I see now is that, I can't generate the link with necessary request parameters when I use #ModelAttribute to aggregate these parameters.
I use #ModelAttribute like this not to work with a lot of request parameters in my service:
#GetMapping("/entities")
public Resource<Entity> get(#ModelAttribute Criteria criteria) {
}
When I try to build a link to the method, it does not include accountId that I have in model attribute. I expect it to have as a request parameter.
linkTo(methodOn(MyController.class).get(new Criteria(accountId)))
Is there a way to add #ModelAttribute fields as request parameters? Usually they are sent as request parameters, thus I expected Spring to do it automatically.

Spring boot and validation of param in url

#RequestParam(value = "param") String param
How to validate this param in elegant way ? More exactly I must check if param is some value in database. My stack is: spring-boot+mybatis
This might be a duplicate of that one but anyway.
There's a difference in the way you validate forms and separate parameters. With POST it's actually impossible to break the request into separate parameters and you get the whole post body, and you use #Valid to process it. With GET it is possible to have separate parameters as arguments in method, and in this case Spring proprietary #Validated annotation should be used.

Handling invalid URL's when using #ParamValue in Spring MVC

I am using #ParamValue annotation in my controller (Spring MVC).
Say My valid URL's are:
www.temp.com/test/a,
www.temp.com/test/b and
www.temp.com/test/c
So, my RequestMapping is:
#RequestMapping(value = "/test/{value}", method = RequestMethod.GET)
Now, my problem is that if anyone types a wrong URL like this :
www.temp.com/test/youarebroken
then I have to manually handle such a case in my controller to show 404 or not found.
Isn't there something inbuilt that sends a "not found or 404" notification to server that I can use directly ?
The simplest solution is to define a custom exception handler and to throw the custom exception when a validation fails within your controller. That would require that you manage the conditions manually as you stated you do not want to do.
A different solution is to use a global exception handler and define it to deal with the HTTP errors that are handled by Spring built-in.
In this link you can see both approaches: http://www.journaldev.com/2651/spring-mvc-exception-handling-exceptionhandler-controlleradvice-handlerexceptionresolver-json-response-example
However, from your question I understand you would like to return automatically an exception when certain condition in your param value does not meet, and you do not want to validate this manually within your controller. For this, you can add custom validation for an specific class and then set #Valid before the #ParamValue.
You can check this link for DataBinding http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html
And this link for specific validation on param attributes: Spring Web MVC - validate individual request params
So, in plain a solution would be to define a custom validator that throws a custom exception when fails. To set #Valid for the parameters (check link) and to adjust the custom exception to handle HTTP errors (e.g. HttpStatus.NOT_FOUND).
You can use a regex in your #RequestMapping URL. Example:
#RequestMapping(value = "/test/{value:[a-z]}", method = RequestMethod.GET)

Spring MVC RequestMapping ParamRequest collection/array

I have a #Controller with a #RequestMapping functions that accept collections.
Imagine something like:
requestHandler(Collection<Long> param){
...
}
This mapping only matches when I send requests such as:
http://www.domain.com/mapping/funct?param=1&param=2&param=3
I'd like to match it as well when I send a comma sepparated value:
http://www.domain.com/mapping/funct?param=1,2,3
Is there a way without using .split ? I'd like it to be automatically parsed to a collection.
You would have to write a custom Converter and register it in your Spring MVC context.
It is better to access all query parameters and parse according to your needs in this type of scenarios
You should have access to the requests query string via request.getQueryString().
In addition to getQueryString, the query parameters can also be retrieved from request.getParameterMap() as a Map.

Categories