0

I have a controller method like so

  @RequestMapping(value = "/update", method = RequestMethod.POST)
  RestResponse updateId(@RequestParam(value = "cityId") Optional<Integer> cityId) {
  }

Now when I send cityId without a value, cityId.isPresent() returns false, which is wrong because I actually included cityId in my request parameters but I just didn't set a value.

I noticed this behavior doesn't happen on Optional<String>, it actually tells me that the parameter is present even if it doesn't have a value.

So how should I handle parameters the likes of Optional<Integer>? I just need to determine that the parameter was sent even if it had no value (because it's optional and if it was sent without a value I have to update the database)

edit: Looks like what I wrote above is confusing, I'll try to describe the issue again

@RequestMapping(value = "/temp", method = RequestMethod.POST)
void temporary(@RequestParam(value = "homeCityId") Optional<Integer> homeCityId) {
    if(homeCityId.isPresent()) {
        System.out.println("homeCityId is Present");
    } else {
        System.out.println("homeCityId is Not Present");
    }
}

I make a request that includes homeCityId with an empty value, I get homeCityId is Not Present. How can I distinguish between a request that have homeCityId with an empty value and a request that didn't include homeCityId at all?

prettyvoid
  • 3,446
  • 6
  • 36
  • 60
  • I don't understand _even if it doesn't have a value_. If it's present, what does `cityId.get()` return? – Sotirios Delimanolis Jan 05 '16 at 15:39
  • Personally I wouldn't use an `Optional` for that scenario. You're basically checking `null` anyway. – Makoto Jan 05 '16 at 15:39
  • @SotiriosDelimanolis cityId.get() throws an exception `NoSuchElementException`, but the cityId was sent via the request, it just doesn't have a value. I tried to go a bit low level and I checked the `ServletRequest` in my Token Filter and indeed cityId is there but it doesn't get passed to the controller for some reason. screenshot http://i.imgur.com/CP9cytQ.png – prettyvoid Jan 05 '16 at 15:46
  • @Makoto so what would you use? The other approach I could think of is `@RequestParam(value = "cityId", required = false) Integer cityId` and that doesn't work for me too because there is no way to distinguish if the parameter was sent or not (if it had no value) – prettyvoid Jan 05 '16 at 15:47
  • 1
    This is very confusing. Please edit your question. You're saying it's present in the request, not that `cityId.isPresent()` returns true (because it wouldn't throw an exception if it did). In your image, it's `homeCityId`. In your code, it's `cityId`. I'm having a hard time believing what you're posting so please edit everything and add a [MCVE]. – Sotirios Delimanolis Jan 05 '16 at 15:47
  • @SotiriosDelimanolis Sorry, I tried to make it a bit more clearer. – prettyvoid Jan 05 '16 at 15:57
  • If you're using `Optional`, either it's present and has a non-null `Integer` value, or it's not present and doesn't. There's no `Integer` value, other than `null`, that can indicate lack of value, but with `Optional`, you can't have `null`. – Sotirios Delimanolis Jan 05 '16 at 16:10
  • @SotiriosDelimanolis Thanks for the information, could you suggest a way to achieve what I want as an answer? I have to distinguish if the integer was sent without a value or not sent at all. I thought of converting the parameter to String (then if it had no value i'd get an empty string) but that requires me to cast the string to int, etc.. doesn't sound like good code. Could you suggest anything please? Thanks again – prettyvoid Jan 05 '16 at 16:20

1 Answers1

1

How can I distinguish between a request that have homeCityId with an empty value and a request that didn't include homeCityId at all?

You'll have to handle the case of homeCityId being present, regardless of empty or not, as a single case. Then you'll need another handler for absence.

First, you can use @RequestMapping#params to set homeCityId as a necessary parameter mapping for the handler to be invoked.

@RequestMapping(value = "/temp", params = { "homeCityId" }, method = RequestMethod.POST)
public String present(@RequestParam(value = "homeCityId") Integer homeCityId) {

Then check if homeCityId is null or not.

Second, have a second handler that doesn't require the homeCityId param.

@RequestMapping(value = "/temp", method = RequestMethod.POST)
public String notPresent() {

Spring MVC will always invoke the first if the parameter is present (and you'll have access to its value. It will invoke the second if the parameter is absent. Since it's absent, there's no value for you to worry about.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Thanks for the answer, what if I have a controller method that takes a large number of parameters, for example 15 optional integers, looks like that would needs a lot of different methods to take all cases into consideration, right? – prettyvoid Jan 05 '16 at 20:12