Search code examples
javaspringhttpspring-bootresttemplate

UriComponentsBuilder - how to replace some of the queryParams and remove the unused?


Hey i have this url that contains multiple query params - it is used for search. It's a hatehoas link

https://someurl/customers?customer-id={customer-id}&type={type}&something={something}

And i wish to replace only two of the the params

Map<String, String> params = new HashMap<>();
    params.put("customer-id", customerId);
    params.put("something", something)

    UriComponents customerUrl = UriComponentsBuilder
          .fromHttpUrl(specialURL)
          .buildAndExpand(params).encode();

But this throws.

java.lang.IllegalArgumentException: Map has no value for 'type'
    at org.springframework.web.util.UriComponents$MapTemplateVariables.getValue(UriComponents.java:346) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]

What is the best workaround here, let's say I have around 7 params, replacing them by an empty string or cutting string in half seems rather hacky.


Solution

  • UriComponents is always expect all the key data must be present in the map, below is the code which is used by UriComponents which throws the exception.

    @Override
    public Object getValue(String name) {
        if (!this.uriVariables.containsKey(name)) {
            throw new IllegalArgumentException("Map has no value for '" + name + "'");
        }
        return this.uriVariables.get(name);
    }
    

    Solution:

    So to solve your problem you can try following code.

    class Param extends HashMap<String, String>{
    
    
        @Override
        public String get(Object key) {
            if(!super.containsKey(key)){
                super.put(key.toString(), "");
            }
            return super.getOrDefault(key, "t");
        }
    
        @Override
        public boolean containsKey(Object arg0) {
            return true;
        }   
    }
    
    public class UriComponenet {
    
        public static void main(String[] args) {
    
            Param params = new Param();
            params.put("customer-id", "1");
            String specialURL="https://someurl/customers?customer-id={customer-id}&type={type}&something={something}";
            UriComponents customerUrl = UriComponentsBuilder
                  .fromHttpUrl(specialURL)
                  .buildAndExpand(params).encode();
    
            System.out.println(customerUrl);        
        }
    }
    

    I have extends the HashMap class to Param and then use that class as an input to buildAndExpand method.

    I hope this will solve your problem.