Json
Ratpack has built-in JSON support using Jackson. JSON is available as standard and does not require a separate ratpack-jackson module.
@Data
@AllArgsConstructor
@NoArgsConstructor
public static final class User {
private int id;
private String name;
}
public static void main( String[] args ) throws Exception {
Action<Chain> handlers = chain -> {
chain.all( ctx -> {
ctx.byMethod( m -> {
m.get( iCtx -> iCtx.render( Jackson.json( new User( 123, "John" ) ) ) );
m.post( iCtx -> iCtx.parse( Jackson.fromJson( User.class ) ).then( user -> {
iCtx.render( "Received user: " + user );
} ) );
// m.post( iCtx -> iCtx.parse( User.class ).then( user -> {
// iCtx.render( "Received user: " + user );
// } ) );
} );
} );
};
RatpackServer.start( server -> server
.serverConfig( ServerConfig.builder().development( true ).build() )
.handlers( handlers ) );
}
(I'm using lombok)
It's easy to use, just wrap it in each method of ratpack.jackson.Jackson. Marshall / unmarshall objects through Jackson. Jackson.fromJson () can be omitted and replaced with the commented out part. This is because the NoOptParserSupport for when the raw Class is passed is automatically added.
Registry and Renderer, Parserrender () takes ʻObject as an argument, and parse () takes any Class as an argument. At this time, it is necessary to convert from ʻObject to an appropriate HTTP response. As I mentioned a bit earlier, this conversion uses the Renderer and Parser classes registered in the Registry. It will be converted appropriately by being called according to the requested person. Therefore, you can achieve your own conversion by registering your own custom renderer in the registry.
Here, as an example, let's create a mechanism for receiving and returning data in CSV. ʻUser` is the same as the above example.
First, define Renderer.
public static final class UserRenderer extends RendererSupport<User> {
@Override
public void render( Context ctx, User user ) throws Exception {
ctx.getResponse().contentType( "text/plain" );
ctx.render( user.getId() + "," + user.getName() );
}
}
It inherits from RendererSupport, which is the skeleton of the Render interface. When Context.render () in the handler is called with ʻUser as an argument, this renderer that can output the ʻUser class is called. The arguments are the Context of the request and the ʻUser passed to render () `. I think it's almost as you would expect. The method of outputting the response is the same as when I was doing it with the handler.
public static final class UserParser extends NoOptParserSupport {
@Override
protected <T> T parse( Context context, TypedData requestBody, TypeToken<T> type ) throws Exception {
if ( type.getRawType().equals( User.class ) ) {
String[] csv = requestBody.getText().split( "," );
User user = new User( Integer.parseInt( csv[0] ), csv[1] );
return Types.cast( user );
} else {
return null;
}
}
}
Like the renderer, the parser inherits the NoOptParserSupport skeleton that implements the Parser interface. NoOptParserSupport is used to provide the simplest parser, especially whenparse (Class)is called. If TypeToken, that is, the person requested is not ʻUser, returns null` to indicate that this parser cannot handle it.
public static final class CustomHandler implements Handler {
@Override
public void handle( Context ctx ) throws Exception {
ctx.byMethod( m -> {
m.get( iCtx -> {
iCtx.render( new User( 123, "John" ) );
} );
m.post( iCtx -> {
iCtx.parse( User.class ).then( user -> {
iCtx.render( "Received: " + user );
} );
} );
} );
}
}
In order to show the behavior when registering in the registry, I also tried to make the handler an independent class here.
public static void main( String[] args ) throws Exception {
RatpackServer.start( server -> server
.serverConfig( ServerConfig.builder().development( true ) )
.registryOf( spec -> {
spec.add( new UserRenderer() )
.add( new UserParser() )
.add( new CustomHandler() );
} )
.handler( CustomHandler.class ) );
}
You need to register your own class in Registry. Notice that we are passing the handler () method to the Class, not the instance.
$ curl localhost:5050 && echo
123,John
$ curl -X POST localhost:5050 --data "456,Jack" && echo
Received: Sample5_2_Registry.User(id=456, name=Jack)
I was able to confirm that CSV is being processed through a renderer and parser that is uniquely defined.
Recommended Posts