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
, Parser
render ()
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