Suppose we have a service with the following contract:
public interface CategoryService {
public int createNew(String languageCode, String name, String descriptionMarkdown, Integer parentCategoryID, String createdByUserName) throws ServiceException;
};
How do I map the int
return type to produce a JSON value like the following?
PS: I know that the createNew
method will have to be an HTTP POST request (annotation @POST
). Assumes annotations are there. I just need the response representation.
{"id": 1}
Not sure if it's a good idea. Would be much better if you'll create new JAX-RS resource and designated entity-class to response with.
Still, if you want to mix marshalling with model, you could write your own MessageBodyWriter. For example:
@Produces("application/json")
public class IntWriter implements MessageBodyWriter<Integer> {
@Override
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
boolean intAsID = false;
for (Annotation a : annotations) {
if (a.annotationType().getCanonicalName().equals("com.blabla.IntAsID")) {
intAsID = true;
break;
}
}
return intAsID && (type == Integer.class);
}
@Override
public long getSize(Integer integer, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return 0;
}
@Override
public void writeTo(Integer integer, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
JsonGenerator generator = Json.createGenerator(entityStream);
generator.writeStartObject()
.write("id", integer)
.writeEnd()
.flush();
}
}
Several keypoints here.
1.
Don't forget to register this writer in your configuration.
public class ServerConfig extends Application {
private static final Set<Class<?>> classes
= new HashSet<>();
static {
//register your resources
classes.add(Test.class);
//register message body writer
classes.add(IntWriter.class);
}
@Override
public Set<Class<?>> getClasses() {
return classes;
}
}
2.
If you don't want to use use this writer for every resource returning int. Create some special annotation for your resource (for example IntAsID).
@Retention(RetentionPolicy.RUNTIME)
public @interface IntAsID {}
Don't forget to set correct retention policy. And check presence of this annotation in isWriteable
method. Like I did in my example.
And yes, add this annotation to your resource:
public interface CategoryService {
@IntAsID
public int createNew(String languageCode, String name, String descriptionMarkdown, Integer parentCategoryID, String createdByUserName) throws ServiceException;
};
3.
Use @Produces
annotation. That will help your JAX-RS provider to don't check this writer in cases then Resource should produce not JSON, but something else.
4.
Don't care about getSize()
method. Its result is ignored now (at least in Jersey).
5.
Don't close entityStream
in writeTo
method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.