Last active
          September 15, 2018 04:43 
        
      - 
      
 - 
        
Save romain-grecourt/d2b04178140f7eab3b69f8ea2481fc10 to your computer and use it in GitHub Desktop.  
    helidon jsonb support
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | public class JsonbSupport implements Service, Handler { | |
| private final Jsonb jsonb; | |
| private final Class type; | |
| private final Type runtimeType; | |
| private JsonbSupport(Class type, Type runtimeType, JsonbConfig config){ | |
| Objects.requireNonNull(type, "type is null"); | |
| this.type = type; | |
| this.runtimeType = runtimeType; | |
| if(config != null){ | |
| jsonb = JsonbBuilder.create(config); | |
| } else { | |
| jsonb = JsonbBuilder.create(); | |
| } | |
| } | |
| @Override | |
| public void update(Routing.Rules routingRules) { | |
| routingRules.any(this); | |
| } | |
| @Override | |
| public void accept(ServerRequest req, ServerResponse res) { | |
| // Reader | |
| req.content() | |
| .registerReader(type::isAssignableFrom, (publisher, clazz) -> { | |
| return reader().apply(publisher); | |
| }); | |
| // Writer | |
| res.registerWriter(obj -> (type.isAssignableFrom(obj.getClass())) | |
| && testOrSetContentType(req, res), | |
| bean -> { | |
| return writer().apply(bean); | |
| }); | |
| req.next(); | |
| } | |
| private boolean testOrSetContentType(ServerRequest request, ServerResponse response) { | |
| MediaType mt = response.headers().contentType().orElse(null); | |
| if (mt == null) { | |
| // Find if accepts any JSON compatible type | |
| List<MediaType> acceptedTypes = request.headers().acceptedTypes(); | |
| MediaType preferredType; | |
| if (acceptedTypes.isEmpty()) { | |
| preferredType = MediaType.APPLICATION_JSON; | |
| } else { | |
| preferredType = acceptedTypes | |
| .stream() | |
| .map(clazz -> { | |
| if (clazz.test(MediaType.APPLICATION_JSON)) { | |
| return MediaType.APPLICATION_JSON; | |
| } else if (clazz.hasSuffix("json")) { | |
| return new MediaType(clazz.getType(), clazz.getSubtype()); | |
| } else { | |
| return null; | |
| } | |
| }) | |
| .filter(Objects::nonNull) | |
| .findFirst() | |
| .orElse(null); | |
| } | |
| if (preferredType == null) { | |
| return false; | |
| } else { | |
| response.headers().contentType(preferredType); | |
| return true; | |
| } | |
| } else { | |
| return MediaType.JSON_PREDICATE.test(mt); | |
| } | |
| } | |
| public Reader<Object> reader() { | |
| return (publisher, clazz) -> { | |
| // TODO issue when using inputstream reader. | |
| // seems to point at a bug in the publisher inputstream impl in webserver | |
| return ContentReaders.stringReader(Charset.defaultCharset()) | |
| .apply(publisher) | |
| .thenApply(str -> { | |
| if (runtimeType != null) { | |
| return jsonb.fromJson(str, runtimeType); | |
| } | |
| return jsonb.fromJson(str, type); | |
| }); | |
| }; | |
| } | |
| public Function<Object, Publisher<ResponseChunk>> writer() { | |
| return obj -> { | |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); | |
| jsonb.toJson(obj, baos); | |
| return ContentWriters.byteArrayWriter(false) | |
| .apply(baos.toByteArray()); | |
| }; | |
| } | |
| public static class Builder { | |
| private Class type; | |
| private Type runtimeType; | |
| private JsonbConfig config; | |
| public Builder type(Class type){ | |
| this.type = type; | |
| return this; | |
| } | |
| public Builder runtimeType(Type type){ | |
| this.runtimeType = type; | |
| return this; | |
| } | |
| public Builder config(JsonbConfig config){ | |
| this.config = config; | |
| return this; | |
| } | |
| public JsonbSupport build(){ | |
| return new JsonbSupport(type, runtimeType, config); | |
| } | |
| } | |
| public static Builder builder(){ | |
| return new Builder(); | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | private static Routing createRouting() { | |
| return Routing.builder() | |
| .register(JsonbSupport.builder() | |
| .type(Dog.class) | |
| .config(new JsonbConfig() | |
| .withNullValues(true)) | |
| .build()) | |
| .post("/test", Main::test) | |
| .build(); | |
| } | |
| private static void test(ServerRequest req, ServerResponse res){ | |
| req.content() | |
| .as(Dog.class) | |
| .thenAccept(res::send); | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | <dependency> | |
| <groupId>javax.json.bind</groupId> | |
| <artifactId>javax.json.bind-api</artifactId> | |
| <version>1.0</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.eclipse</groupId> | |
| <artifactId>yasson</artifactId> | |
| <version>1.0.1</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>org.glassfish</groupId> | |
| <artifactId>javax.json</artifactId> | |
| <version>1.1.2</version> | |
| </dependency> | |
| <dependency> | |
| <groupId>javax.json</groupId> | |
| <artifactId>javax.json-api</artifactId> | |
| <version>1.1.2</version> | |
| </dependency> | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | curl -vvv -H "Content-Type: application/json" -d '{"age":4,"bitable":false,"name":"Falco"}' http://localhost:8080/test | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment