I have this QueryMapping method where I have some parameters marked as required in my GrapthQL schema, but not all. Using #Argument allows me to grab all required parameters, but when I send a Query without an optional parameter it crashes. Using the RequestParam annotation with a default value doesn't work since its type is an integer and the annotation requires a string. (I guess it's supposed to be called within a REST-API)
#QueryMapping
public List<Record> getRecord(Argument String email, #Argument int dateFrom, #RequestParam(required = false, defaultValue = 0) int dateTo) {
return repository.findSpecific(email, dateFrom);
}
Edit: Method overloading does not work.
What can I do?
I found a solution by using Kotlin: Adding a Question mark behind the Parameter Type allows me to set the value to null.
Related
I am trying to add a default value to an optional header parameter for when it is not present. However, when the parameter is not included, I noticed that it is not being populated with the default value:
public Mono<User> getUser(
#RequestHeader(value = "accept", defaultValue = "abc") String acceptHeader,
...
)
When I am debugging the code, acceptHeader is "/" when no the param is not specified. I looked online and could not find any reason as to why this is happening. Not sure if it makes a difference, but I am making the call with Postman. Does anyone have any idea why this is happening? I could implement code to handle this logic inside getUser but I would like to ideally use annotations.
/ is a default value so is not empty and defaultValue = "abc" doesn't work. If you want to do something when nothing was put into accept value use this instead it defaultValue = "abc":
if (acceptHeader.eqals("/") {
... do something
}
I have an Interface method which can be called as below -
{{url}}/packageName/{{var}}/list
It can take in a param of type Collection<String> , so i can fetch specific results.
{{url}}/packageName/{{var}}/list?paramIds=param1¶mIds=param2
Now if i leave paramIds empty as below, Spring MVC creates LinkedHashMap , size 0 and i get no results back.
{{url}}/packageName/{{var}}/list?paramIds=
This is my annotation #RequestParam(value = "paramIds", required = "false") Collection<String> paramIds
I tried to get rid of required and use defaultValue but unable to set defaultValue to null.
For now i changed the annotation to #RequestParam(value = "paramIds", defaultValue = "none") and added code in the dao to handle "none" as null - wondering if there is a better way to solve this problem.
Thanks in advance.
It sounds to me like Spring is giving you the best option, an empty list is usually better than a null.
My first choice would be to modify your DAO code to handle an empty list instead of expecting null, but assuming that's not possible, why not have a check in your controller to pass null to your DAO if the collection is empty, like:
if (paramsIds.isEmpty()) {
dao.doSomething(null);
}
Using java jersey, I have the following #QueryParam's in my method handler:
#Path("/hello")
handleTestRequest(#QueryParam String name, #QueryParam Integer age)
I know if I do:
http://myaddress/hello?name=something
It will go into that method....
I want to make it so that I can call:
http://myaddress/hello?name=something
And it will also go into that same method. Is there any way I can flag an "optional" PathParam? Does it work with #FormParam too? Or am I required to create a separate method with a different method signature?
In JAX-RS parameters are not mandatory, so if you do not supply an age value, it will be NULL, and your method will still be called.
You can also use #DefaultValue to provide a default age value when it's not present.
The #PathParam parameter and the other parameter-based annotations, #MatrixParam, #HeaderParam, #CookieParam, and #FormParam obey the same rules as #QueryParam.
Reference
You should be able to add the #DefaultValue annotation the age parameter, so that if age isn't supplied, the default value will be used.
#Path("/hello")
handleTestRequest(
#QueryParam("name") String name,
#DefaultValue("-1") #QueryParam("age") Integer age)
According to the Javadocs for #DefaultValue, it should work on all *Param annotations.
Defines the default value of request meta-data that is bound using one of the following annotations: PathParam, QueryParam, MatrixParam, CookieParam, FormParam, or HeaderParam. The default value is used if the corresponding meta-data is not present in the request.
You can always wrap return type in optional, for example: #QueryParam("from") Optional<String> from
#RequestMapping(value = "/Fin_AddBankAccount", method = RequestMethod.POST)
public #ResponseBody JsonResponse addCoaCategory(
#RequestParam(value="code", required=true) long code,
#RequestParam(value="startFrom", required=true) long startFrom,
#RequestParam(value="name", required=true, defaultValue="N/A") String name)
{
}
defaultValue="N/A" not working , As I did not provide any text in name field , it store null in database instead of "N/A"?
What is the point of setting a default value if you really want that parameter.
if you mark it as required true(not needed as it is default) then no need of a default value.
If that parameter is not mandatory then mark it as false and give a default value.
Documentation of Spring RequestParam.required
Default is true, leading to an exception thrown in case of the parameter missing in the request. Switch this to false if you prefer a null in case of the parameter missing.
From your question I figured out that you are sending parameter name with empty value using POST request. According to the Spring documentation you should not send name parameter in the request in order to use default value. Simply remove name field from HTML form if it is empty.
It seems that default values makes more sense for GET requests.
make sure you don't pass empty string value
Valid Methods:
1. Fin_AddBankAccount?name=
O/P: name="N/A"
Fin_AddBankAccount?
O/P: name="N/A"
Invalid Methods:
Fin_AddBankAccount?name=""
this will set empty string to variable i.e. name="";
In my project
#RequestParam(value="name", required=true, defaultValue="N/A") String name
This code correctly sets name variable as defaultvalue N/A when requestparam "name" was not provided. My guess is you are not inserting this name variable into the table properly so database is storing null instead of "N/A". Please show us or double check the data access object code. Good luck
Thanks #TiarĂª Balbi, in fact you do not need "required=true" because defaultValue="N/A" implicitly sets this variable as required=false anyways.
I have a controller with a method signature like this
#RequestMapping(value = "/{project:[A-Z0-9_+\\.\\(\\)=\\-]+}", method = RequestMethod.GET)
public ResponseEntity<Object> lookupProject(#PathVariable String project,
#RequestParam(value = "fields", required = false) String fields,
#RequestParam(value = "asList", required = false, defaultValue = "false") boolean asList);
I am returning for JSON a Collection<Object> or Map<String, Object>. This isn't suitable for XML. I'd rather return a Project object.
Is there a clean way to determine which content type will be produced? The work-around would be another method which produces XML only and returns the Project object. I'd rather like to avoid duplicate code.
I am on Spring 3.1.3-RELEASE.
According to Spring documentation, your produces param will return content based on the Accept, i.e.
#RequestMapping(value="/someUrl/", produces="application/*")
public Project someControllerMethod(...)
If the method takes in application/xml, the method will produce XML, if application/json, it will produce json, etc.
You just need marshallers set up for the appropriate object types.
Documentation here:
http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#produces()
Content type to be produced will depend on type acceptable by the client.One solution for this is already mentioned, using produces attribute.Another solution is using ContentNegotiatingViewResolver, which can resolve views based on accept header or other mechanism.
Refer the documentation http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.html
Example:http://www.mkyong.com/spring-mvc/spring-3-mvc-contentnegotiatingviewresolver-example/
Albeit, I think Dardo's solution is best, you could inspect the object type with your XMLHttpMessageConverter, and cast differently if it's a Project object.
In Spring Framework 4.1 you can use a ResponseBodyAdvice to modify the value returned from an #ResponseBody or ResponseEntity method just before it is written out.
See http://docs.spring.io/spring-framework/docs/4.1.0.RC2/javadoc-api/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyAdvice.html.
I ended up in splitting in two methods.
Public methods have been renamed to lookupAsType. Both delegate/return
String[] fieldsArray = StringUtils.split(fields, ',');
return lookup(project, fieldsArray, asList, mediaType);
The new method lookup has the same code s before but contains not an if clause for the media types.
if (mediaType.equals(MediaType.APPLICATION_JSON)) {
body = projectValues;
} else if (mediaType.equals(MediaType.APPLICATION_XML)) {
body = new Project(projectValues);
} else {
throw new NotImplementedException("Project lookup is not implemented for media type '" + mediaType + "'");
}
The bad thing is that MediaType is not a enum but an ugly class.