How to send json with GET params via Spring Boot / Tomcat?

人盡茶涼 提交于 2021-02-10 20:10:26

问题


so currently I'm working on a project where we have product objects which in turn contain "Origin" objects (containing region: String and country: String).

What I'm trying to do is a RestController which takes in an optional Origin object and does something with it (e.g. logs it).

This is what I have right now:

@GetMapping("search")
    public Page<Wine> getProductByStuff(
            @RequestParam(required = false) Origin origin, 
            /* other attributes */) {
    log.info(origin); // it has a proper toString method.
}

There are two problem with this approach. First of all, when I send a request like:

http://[...]/search?origin={"region":"blah","country":"UK"}

or even the html converted string like:

http://[...]/search?origin={%22region%22:%22blah%22%44%22country%22:%22UK%22}

... it says

Invalid character found in the request target [/api/products/search?origin={%22region%22:%22blah%22%44%22country%22:%22DE%22}]. The valid characters are defined in RFC 7230 and RFC 3986.

Afaik the only valid characters Tomcat has that I need are {}. All others I've replaced with the html encoded chars and it still doesn't work.

What I did to prevent this:

@Component
public class TomcatWebServerCustomizer
        implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        TomcatConnectorCustomizer a = null;
        factory.addConnectorCustomizers(connector -> {
            connector.setAttribute("relaxedPathChars", "<>[\\]^`{|},\"");
            connector.setAttribute("relaxedQueryChars", "<>[\\]^`{|},\"");
        });
    }
}

(See this, which is, by the way, deprecated (at least connector.setAttribute).)

This produced:

MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type '[censored].backend.model.Origin'.

My questions are:

  • (How) is it possible to configure Tomcat/Spring so that they can actually accept json in the url params?
  • How would I format it in e.g. Postman so that it would work? Currently I'm just converting special characters by hand in the params tab of Postman.

回答1:


  • Here is what you need to do if you want to send it as json query param.
     @RestController
     public class OriginController {

      @GetMapping("/search")
      public void getOrigin(@RequestParam(value = "origin", required = false) 
                            Origin origin) {
        System.out.println(origin);
      }

     }
  • Register a converter
    @Component
   public class StringToOriginConverter implements 
                              Converter<String, Origin> {

      ObjectMapper objectMapper = new ObjectMapper();

      @Override
      public Origin convert(String source) {
         try {
            return objectMapper.readValue(source, Origin.class);
         } catch (JsonProcessingException e) {
            //You could throw some exception here instead for custom error
            return null;
         }

       }
    }
  • Sending from postman

Note

My answer is not debating whether you should use POST or GET as it is not what you have asked. It is just providing one option if you want to send some payload as query param




回答2:


As mentioned, don't use JSON as a path parameter.

Directly use path parameters, and convert to Origin object.

@GetMapping("search")
public Page<Wine> getProductByStuff(
        @RequestParam(required = false) String region,
        @RequestParam(required = false) String country, /* other attributes */) {
    Origin origin = new Origin(region, country);
    log.info(origin); // it has a proper toString method.
}


来源:https://stackoverflow.com/questions/63092675/how-to-send-json-with-get-params-via-spring-boot-tomcat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!