i'm using jersey 2.19. support 2 versions of api. that, have 2 main paths: /api/v1 , /api/v2. have 2 packages com.test.v1 (with v1 api resources) , com.test.v2 (with v2 api resources).
i know how define path whole application, use @applicationpath('api') on resourceconfig class. however, how define package com.test.v1 resources live in /v1 namespace, , package com.test.v2 resources live in /v2 namespace? currently, see no other option add 'v1' , 'v2' prefixes in each @path annotation, like: @path('v1/something') or @path('v2/something') prefix each resource. lot of redundancy.
is there better way?
below proof-of-concept 1 way accomplish this. have never used this, can't provide testimony maintainability issues may or or may not come down line larger projects. tested on simple project.
it uses jersey's programmatic resource building api append version original path.
import java.util.hashmap; import java.util.map; import javax.ws.rs.core.configuration; import javax.ws.rs.ext.provider; import org.glassfish.jersey.server.model.modelprocessor; import org.glassfish.jersey.server.model.resource; import org.glassfish.jersey.server.model.resourcemodel; @provider public class versioningmodelprocessor implements modelprocessor { private map<string, string> packageappenders = new hashmap<>(); { packageappenders.put("com.stackoverflow.jersey.v1", "v1"); packageappenders.put("com.stackoverflow.jersey.v2", "v2"); } @override public resourcemodel processresourcemodel(resourcemodel model, configuration config) { // create new resourc model. resourcemodel.builder newmodelbuilder = new resourcemodel.builder(false); (final resource resource: model.getresources()) { // package string path = resource.getpath(); class handlerclass = resource.gethandlerclasses().iterator().next(); string pkg = handlerclass.getpackage().getname(); // match packge our map of packages if (packageappenders.containskey(pkg)) { // append version string version = packageappenders.get(pkg); path = version + "/" + path.replace("/", ""); resource.builder resourcebuilder = resource.builder(resource); resourcebuilder.path(path); resource newresource = resourcebuilder.build(); system.out.println(newresource.tostring()); // add new resource new path. newmodelbuilder.addresource(newresource); } else { // nothing. add resource normal newmodelbuilder.addresource(resource); } } return newmodelbuilder.build(); } @override public resourcemodel processsubresource(resourcemodel model, configuration config) { return model; } } might more trouble it's worth. don't know. can judge.
Comments
Post a Comment