是否可以取消注册球衣组件?

时间:2016-05-30 14:33:44

标签: java jersey jersey-2.0 dropwizard

Dropwizard注册了球衣组件A。我想用我的自定义版本替换此组件。有可能吗?

1 个答案:

答案 0 :(得分:2)

来自文档:

https://jersey.github.io/documentation/latest/message-body-workers.html#providers-selection

这意味着:

如果您有自定义提供程序,则将使用您的自定义提供程序。

以示例:

假设我有一个用户类:

public class User {

    @JsonProperty("name")
    private String name;

    @JsonProperty("password")
    private String password;

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

我们有一个资源返回用户:

@Path("/hello/world2")
@Produces(MediaType.APPLICATION_JSON)
public class MsgBodyWriterTest {

    @GET
    @Path("/v1")
    @Produces(MediaType.APPLICATION_JSON)
    public User test() {
        User u = new User();
        u.setName("Test");
        return u;
    }
}

我们有一个处理此User对象的MessageBodyWriter:

@Provider
public class UserMsgBodyWriter implements MessageBodyWriter<User> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        return type == User.class;
    }

    @Override
    public long getSize(User t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeTo(User t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
            throws IOException, WebApplicationException {

        System.out.println("Use custom Provider");
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(entityStream, t);
    }

}

然后我们通过注册资源和提供者将事物连接在一起:

public class Starter extends Application<Configuration> {

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        environment.jersey().register(MsgBodyWriterTest.class);
        environment.jersey().register(UserMsgBodyWriter.class);
    }

    public static void main(String[] args) throws Exception {
        new Starter().run("server", "/Users/artur/dev/repo/dw-test/src/main/resources/configuration.yaml");
    }

}

启动时,它会发布泽西资源,然后我们可以访问它:

arturk:~ artur$ curl -XGET  "localhost:9085/hello/world2/v1"

然后记录:

Use custom Provider
0:0:0:0:0:0:0:1 - - [02/Jun/2016:09:21:31 +0000] "GET /hello/world2/v1 HTTP/1.1" 200 31 "-" "curl/7.43.0" 30

请注意输出:“使用自定义提供程序”。这只是为了证明已经调用了正确的提供者。

我希望这就是你要找的东西。

简而言之,挂钩的默认提供程序来自Jaxb。它处理所有json类型并启用默认bean序列化。没有它,你的json将不知道如何解析。你不想摆脱它,而是添加它。 通过创建自己的提供商,选择将为您选择正确的选择。默认情况下,jersey将在默认提供程序之前对自定义提供程因此,只要正确实现了isWriteable()方法,就会选择您的提供程序来完成工作。

编辑:

回答你的实际问题。如果您必须摆脱DW注册的提供商,那么也有办法。您将不得不覆盖默认服务器工厂。看看:

AbstractServerFactory#createAppServlet。这是默认提供程序所在的位置。再次,如果您只是注册自己的,默认将永远不会被使用,您将节省自己创建服务器工厂的工作(这也是相当容易和直接的你想要)。

干杯,

阿图尔