How do I retrieve query parameters in a Spring Boot controller?
Asked Answered
D

7

220

I am developing a project using Spring Boot. I've a controller which accepts GET requests.

Currently I'm accepting requests to the following kind of URLs:

http://localhost:8888/user/data/002

but I want to accept requests using query parameters:

http://localhost:8888/user?data=002

Here's the code of my controller:

@RequestMapping(value="/data/{itemid}", method = RequestMethod.GET)
public @ResponseBody
item getitem(@PathVariable("itemid") String itemid) {   
    item i = itemDao.findOne(itemid);              
    String itemname = i.getItemname();
    String price = i.getPrice();
    return i;
}
Dosage answered 25/8, 2015 at 10:22 Comment(2)
@RequestParam (good starting point: the official guide)Barytes
> #32201941Fortress
W
306

Use @RequestParam

@RequestMapping(value="user", method = RequestMethod.GET)
public @ResponseBody Item getItem(@RequestParam("data") String itemid){

    Item i = itemDao.findOne(itemid);              
    String itemName = i.getItemName();
    String price = i.getPrice();
    return i;
}
Wold answered 25/8, 2015 at 11:11 Comment(7)
then what is the URL of this method can you please tell ? What should i have to changeDosage
sorry bro this URL is not working localhost:8888/user?data=001 I have enter this URLDosage
Remove value="/" from the request mapping annotation. Btw this is really poor design. If you're going to access an item for a user then the rest way would be user/items/{itemId}.Wold
Using @RequestParam as public @ResponseBody item getitem(@RequestParam("data") String itemid){ requires data query parameter to be always present. Instead if you use it this way public @ResponseBody item getitem(@RequestParam Map<String, String> queryParameters){ , it makes data to be optionalReider
@SampathSurineni it should be Map<String, String[]> queryParameters instead.Billington
@samsri, or just use @RequestParam(name = "data", required = false)Sonnnie
Latest looks like: If the method parameter is Map<String, String> or MultiValueMap<String, String> and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.Uppish
S
34

While the accepted answer by afraisse is absolutely correct in terms of using @RequestParam, I would further suggest to use an Optional<> as you cannot always ensure the right parameter is used. Also, if you need an Integer or Long just use that data type to avoid casting types later on in the DAO.

@RequestMapping(value="/data", method = RequestMethod.GET)
public @ResponseBody
Item getItem(@RequestParam("itemid") Optional<Integer> itemid) { 
    if( itemid.isPresent()){
         Item i = itemDao.findOne(itemid.get());              
         return i;
     } else ....
}
Stagecoach answered 19/5, 2019 at 23:31 Comment(6)
where did you get Optional from?Stylolite
@JoeyGough introduced in Java 8. docs.oracle.com/javase/8/docs/api/java/util/Optional.htmlStagecoach
It's a bad idea to put Optional in parameter. Don't use Optional in parameters. For this problem, you can use required = false.Cf
@Cf why is it a bad idea to use Optional?Showthrough
@hemanth5636, because you can have 3 possible values and not 2 ... (rules.sonarsource.com/java/RSPEC-3553)Cf
But in this case Spring MVC will always populate it. So it will never be null.Astragalus
P
19

To accept both @PathVariable and @RequestParam in the same /user endpoint:

@GetMapping(path = {"/user", "/user/{data}"})
public void user(@PathVariable(required=false,name="data") String data,
                 @RequestParam(required=false) Map<String,String> qparams) {
    qparams.forEach((a,b) -> {
        System.out.println(String.format("%s -> %s",a,b));
    }
  
    if (data != null) {
        System.out.println(data);
    }
}

Testing with curl:

  • curl 'http://localhost:8080/user/books'
  • curl 'http://localhost:8080/user?book=ofdreams&name=nietzsche'
Polak answered 11/11, 2020 at 9:52 Comment(2)
what if you want to pass negatives, like &name!=nietzsche ?Ineradicable
You can simply introduce another request parameter and put the unwanted name there :)Bonilla
T
8

To accept both Path Variable and query Param in the same endpoint:

@RequestMapping(value = "/hello/{name}", method = RequestMethod.POST)
    public String sayHi(
            @PathVariable("name") String name, 
            @RequestBody Topic topic,
            //@RequestParam(required = false, name = "s") String s, 
            @RequestParam Map<String, String> req) {
        
        return "Hi "+name +" Topic : "+ topic+" RequestParams : "+req;
    }

URL looks like : http://localhost:8080/hello/testUser?city=Pune&Pin=411058&state=Maha

That answered 20/4, 2021 at 18:26 Comment(0)
F
5

In Spring boot: 2.1.6, you can use like below:

    @GetMapping("/orders")
    @ApiOperation(value = "retrieve orders", response = OrderResponse.class, responseContainer = "List")
    public List<OrderResponse> getOrders(
            @RequestParam(value = "creationDateTimeFrom", required = true) String creationDateTimeFrom,
            @RequestParam(value = "creationDateTimeTo", required = true) String creationDateTimeTo,
            @RequestParam(value = "location_id", required = true) String location_id) {

        // TODO...

        return response;

@ApiOperation is an annotation that comes from Swagger api, It is used for documenting the apis.

Fend answered 27/7, 2020 at 3:17 Comment(1)
required = true by defaultHandicraft
J
4

I was interested in this as well and came across some examples on the Spring Boot site.

   // get with query string parameters e.g. /system/resource?id="rtze1cd2"&person="sam smith" 
// so below the first query parameter id is the variable and name is the variable
// id is shown below as a RequestParam
    @GetMapping("/system/resource")
    // this is for swagger docs
    @ApiOperation(value = "Get the resource identified by id and person")
    ResponseEntity<?> getSomeResourceWithParameters(@RequestParam String id, @RequestParam("person") String name) {

        InterestingResource resource = getMyInterestingResourc(id, name);
        logger.info("Request to get an id of "+id+" with a name of person: "+name);

        return new ResponseEntity<Object>(resource, HttpStatus.OK);
    }

See here also

Joniejonina answered 9/4, 2019 at 14:19 Comment(0)
M
0

When using the @GetMapping annotation, you typically use @RequestParam in the request instead of @RequestBody. If you want to use @RequestBody, you should use the @PostMapping annotation in the API method.

Matusow answered 28/4 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.