206

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;
}
M. Justin
  • 14,487
  • 7
  • 91
  • 130
Mehandi Hassan
  • 2,381
  • 4
  • 16
  • 20
  • 11
    [`@RequestParam`](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html) (good starting point: [the official guide](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html)) – kryger Aug 25 '15 at 10:45

6 Answers6

294

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;
}
my-
  • 604
  • 9
  • 17
afraisse
  • 3,362
  • 1
  • 12
  • 13
  • 1
    then what is the URL of this method can you please tell ? What should i have to change – Mehandi Hassan Aug 28 '15 at 04:57
  • sorry bro this URL is not working localhost:8888/user?data=001 I have enter this URL – Mehandi Hassan Aug 28 '15 at 05:54
  • 3
    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}**. – afraisse Aug 28 '15 at 06:10
  • 32
    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 queryParameters){` , it makes **data** to be optional – samsri Jan 19 '18 at 09:13
  • @SampathSurineni it should be `Map queryParameters` instead. – Downhillski Oct 11 '18 at 19:17
  • @samsri, or just use `@RequestParam(name = "data", required = false)` – Leponzo Aug 30 '22 at 21:43
30

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 ....
}
my-
  • 604
  • 9
  • 17
Andrew Grothe
  • 2,562
  • 1
  • 32
  • 48
17

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'
daparic
  • 3,794
  • 2
  • 36
  • 38
7

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

satish gupta
  • 71
  • 1
  • 1
6

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.

Shashank
  • 709
  • 8
  • 16
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

TKPhillyBurb
  • 91
  • 3
  • 11