Spring #RequestMapping with optional parameters - java

I have problem in my controller with optional params in requestmapping, look on my controller below:
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Books>> getBooks() {
return ResponseEntity.ok().body(booksService.getBooks());
}
#GetMapping(
produces = MediaType.APPLICATION_JSON_VALUE,
params = {"from", "to"}
)
public ResponseEntity<List<Books>>getBooksByFromToDate(
#RequestParam(value = "from", required = false) String fromDate,
#RequestParam(value = "to", required = false) String toDate)
{
return ResponseEntity.ok().body(bookService.getBooksByFromToDate(fromDate, toDate));
}
Now, when I send request like:
/getBooks?from=123&to=123
it's ok, request goes to "getBooksByFromToDate" method
but when I use send something like:
/getBooks?from=123
or
/getBooks?to=123
it goes to "getAlerts" method
Is it possible to make optional params = {"from", "to"} in #RequestMapping ? Any hints?

Use the default values. Example:-
#GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Books>> getBooksByFromToDate(#RequestParam(value = "from", required = false, defaultValue="01/03/2018") String fromDate, #RequestParam(value = "to", required = false, defaultValue="21/03/2018") String toDate) {
....
}

Just use defaultValue as explained in the Spring's docs:
defaultValue
The default value to use as a fallback when the request parameter is
not provided or has an empty value.

Related

Document a multipart/form-data endpoint with Springfox

I have a POST endpoint which receives a #ModelAttribute parameter. Everything is working ok, but the swagger documentation fails to have the descriptions, examples, etc.
I am using java 11, springboot 2.5.4 and springfox-boot-starter 3.0.0
Here is my code:
#Api
#RestController
#RequestMapping("/foo")
#Validated
public class MyRest {
#PostMapping(value = "/{id}/bar", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
#ApiOperation(value = "Do nothing", notes = "This endpoint does nothing")
public ResponseEntity<String> search(
#ModelAttribute MyModelRequest request,
#ApiParam(value = "Folder ID", required = true)
#PathVariable String id) {
// some business code
return new ResponseEntity<>("lorem ipsum", HttpStatus.OK);
}
}
MyModelRequest
#ApiModel
#Data
public class MyModelRequest {
#ApiParam(name = "fileName", value = "The name of the image to be stored in database")
#ApiModelProperty(value = "name model description", example = "summer picture", required = true)
private String name;
#DecimalMin("0.00")
#DecimalMax("100.00")
#ApiParam(name = "accuracy", value = "The required accuracy")
#ApiModelProperty(value = "Minimum required accuracy", example = "95.15", required = false)
private BigDecimal accuracy;
#ApiParam(name = "marginTop", value = "Top margin of the image")
#ApiModelProperty(value = "Separation between top item and the image", example = "300", required = false)
private Integer marginTop;
#ApiParam(name = "image")
#ApiModelProperty(value = "The image to be stored", example = "vacations.png", required = true)
private MultipartFile image;
}
And this is the generated swagger doc
UPDATE: I noticed that if I change the consumes = { MediaType.MULTIPART_FORM_DATA_VALUE } for consumes = { MediaType.APPLICATION_JSON_VALUE } or remove the whole "consumes" parameter from the endpoint, the documentation shows up correctly, however, doing this will make the fileupload fail.

Filter object from list based on property value spring boot

I have a rest service that will return List of objects
public class MyObject {
private String name;
private String state;
}
Now, I need to filter object from list based on fields provided on rest call:
http://localhost:8080/myuri?state=NY
Now, I need to develop custom filter and I did only find property filter not something like I want. Is there a way to achieve this.
You do not need to use Jackson to do this. Just filter it using Stream API. If data, are loaded from DB, filter it using SQL's WHERE clause.
Example:
#GetMapping(value = "/states", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<MyObject> loadStates(#RequestParam(name = "state", defaultValue = "NY", required = false) String[] states) {
return service.loadAndFilterByState(states);
}
If you have a cached list, you can filter it like below:
#GetMapping(value = "/states", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<MyObject> loadStates(#RequestParam(name = "state", defaultValue = "NY", required = false) String[] states) {
Arrays.sort(states);
return getStates()
.stream()
.filter(s -> Arrays.binarySearch(states, s.getState()) > -1)
.collect(Collectors.toList());
}
See also:
Binding a list in #RequestParam

How to get param in url like /api/groups?sdk&type=1 with java?

For example, URL can be:
/api/groups?sdk&type=1
or
/api/groups?app&type=1
In java, I want to know the param in the url is sdk or app.
I have tried something like:
#RequestMapping(method = RequestMethod.GET)
public ResponseResult testGet(HttpServletRequest request, #RequestParam String sdk, #RequestParam int type) {
...
}
Basically you can have 2 methods and use the params variable in the #RequestMapping anotation to discriminate between the methods.
#RequestMapping(method = RequestMethod.GET, params="sdk")
public ResponseResult getSdk(HttpServletRequest request, #RequestParam int type) {
...
}
#RequestMapping(method = RequestMethod.GET, params="app")
public ResponseResult getApp(HttpServletRequest request, #RequestParam int type) {
...
}
You may or may not need to add the value = "/groups" to your request mapping, depending on how you have configured your class/app.
you can use a parameter for app and sdk so your url will be /api/groups?param=sdk&type=1 or /api/groups?param=app&type=1. you can find sample code below:
#RequestMapping(value = "/groups", method = RequestMethod.GET)
public RestResponse testGet(#RequestParam(value = "param", required = false) String param, #RequestParam(value = "type", required = false) String type) {
}

are these pathParams or pathVariable

I have to write an API call
#GET
#Path("/{settingName1, settingName2}")
public Response getNetworkSettingValue(#ApiParam(value = "Name") #QueryParam("name") String name,
#ApiParam(value = "City") #QueryParam("city") String city,
#ApiParam(value = "State") #QueryParam("state") String state) {}
here my doubt is how to get settingName1 & settingName2 values,
can write like
#ApiParam(value = "SettingName1") #PathParam("settingName1") String settingName1
or
#ApiParam(value = "SettingName1") #PathVariable("settingName1") String settingName1
in method declaration.
or
any other way to get those two values
By the #Path annotation, I assume you are using JAX-RS (Jersey, RESTEasy, etc). So it should be:
#ApiParam(value = "SettingName1") #PathParam("settingName1") String settingName1
If you were using Spring, it should be:
#ApiParam(value = "SettingName1") #PathVariable("settingName1") String settingName1
your annotations are mixed up with spring and swagger.
If u want to accesss pathvariables with spring than it have to be like
#RequestMapping(value = "/{settingName1}/{settingName2}", method = equestMethod.GET)
public Response getNetworkSettingValue(#ApiParam(value = "settingName1") #PathVariable final String settingName1,
#ApiParam(value = "settingName2") #PathVariable final String settingName2) {
...
return new Response();
}

How do I map different values for a parameter in the same #RequestMapping in Spring MVC?

Suppose I have:
#RequestMapping(params = "action=nuovoprodotto")
public ModelAndView nuovoProdotto(
#RequestParam(value = "page", required = false, defaultValue = "-1") int page,
#RequestParam(value = "action") String action,
#ModelAttribute Prodotto prod, HttpSession session)
throws Exception {
is it possible to map this request to like two or three values of "action" parameter?
I tried many ways like
#RequestMapping(params = "action=nuovoprodotto, action=salvaprodotto")
or
#RequestMapping(params = "action=nuovoprodotto|salvaprodotto")
but they don't work... If I can't what are the solutions, besided writing an handler for every single parameter value combination?
Try this:
#RequestMapping(params = {"action=nuovoprodotto","action=salvaprodotto"})
The params attribute is actually of type String[], but annotations let you write a String in place of a single-element String[], so these two are equivalent:
#RequestMapping(params = {"action=nuovoprodotto"})
and
#RequestMapping(params = "action=nuovoprodotto")
Reference:
#RequestMapping.params()
Update: my bad, as you can read in the section Advanced #RequestMapping options, multiple params are combined using and, not or, so it can't work as specified above.
So I'd say what you have to do is create an alias method with almost the same signature:
#RequestMapping(params = "action=nuovoprodotto")
public ModelAndView nuovoProdotto(
#RequestParam(value = "page", required = false, defaultValue = "-1") int page,
#RequestParam(value = "action") String action,
#ModelAttribute Prodotto prod, HttpSession session)
throws Exception {
// some stuff here
}
#RequestMapping(params = "action=salvaprodotto")
public ModelAndView salvaProdotto(
#RequestParam(value = "page", required = false, defaultValue = "-1") int page,
#RequestParam(value = "action") String action,
#ModelAttribute Prodotto prod, HttpSession session)
throws Exception {
return nuovoProdotto(page, action, prod, session);
}

Categories