简体   繁体   中英

@Path annotation: abstract resource in dropwizard

I had an idea to build abstract resource class for my application:

abstract class MyAbstractResource<A> {
    MyAbstractDao dao;

    public MyAbstractResource(MyAbstractDao dao) {
        this.dao = dao;
    }

    @Path("/")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public A create(A account) {
        return dao.create(account);
    }

    @Path("/{id}")
    @PUT
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public A update(A account) {
        return dao.change(account);
    }

    @Path("/{id}")
    @DELETE
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public void delete(@PathParam("id") Long id) {
        dao.delete(id);
    }

    @Path("/{id}")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public A get(@PathParam("id") Long id) {
        return dao.findById(id);
    }

    @Path("/")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Timed
    public List<A> getAll() {
        return dao.findAll();
    }
}

and implementations like:

@Path("/account")
class AccountResource extends MyAbstractResource<AccountDaoImpl> {
    private static final Logger LOG = LoggerFactory.getLogger(AccountResource.class)
}

, but i've faced a problem that @Path-annotation cannot be overridden or added:

Exception in thread "main" javax.servlet.ServletException: org.glassfish.jersey.servlet.ServletContainer-164d01ba@41f867a3==org.glassfish.jersey.servlet.ServletContainer,1,false
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:633)
at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:395)
at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:871)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at com.codahale.metrics.jetty9.InstrumentedHandler.doStart(InstrumentedHandler.java:102)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.handler.RequestLogHandler.doStart(RequestLogHandler.java:140)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.handler.StatisticsHandler.doStart(StatisticsHandler.java:232)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.server.Server.start(Server.java:387)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.Server.doStart(Server.java:354)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at io.dropwizard.cli.ServerCommand.run(ServerCommand.java:43)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:43)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:76)
at io.dropwizard.cli.Cli.run(Cli.java:70)
at io.dropwizard.Application.run(Application.java:73)
at io.dropwizard.Application$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:122)
at com.fappilla.web.FappillaWebService.main(MyWebService.groovy:24)
Caused by: java.lang.IllegalArgumentException: duplicate key: public java.util.List com.fappilla.web.resources.AbstractFappillaResource.getAll()
at jersey.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:119)
at jersey.repackaged.com.google.common.collect.RegularImmutableMap.<init>(RegularImmutableMap.java:67)
at jersey.repackaged.com.google.common.collect.ImmutableMap$Builder.fromEntryList(ImmutableMap.java:249)
at jersey.repackaged.com.google.common.collect.ImmutableMap$Builder.build(ImmutableMap.java:235)
at com.codahale.metrics.jersey2.InstrumentedResourceMethodApplicationListener.onEvent(InstrumentedResourceMethodApplicationListener.java:178)
at org.glassfish.jersey.server.internal.monitoring.CompositeApplicationEventListener.onEvent(CompositeApplicationEventListener.java:74)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:561)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:166)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:327)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:324)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:336)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:358)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:612)
... 40 more

As far as I understand, @Path-annotation is not @Inherited. The question is: how can I implement methods only once for multiple DAOs and resources in such case? Is there any workaround?

PS: I use groovy in my project, but wrote java code above, to let more people give me an advice, so both java and groovy answers are welcome.

Ok, the problem was the "@Timed"-Annotation. Deleting it solved the problem.

In case anyone else comes across this, another solution is to copy InstrumentedResourceMethodApplicationListener.java from https://gist.github.com/mtakaki/746dba30edfefc0ffbd5 onto your classpath - it will get picked up by the classloader over the official class from the metrics jar.

For more information, see:

I've verified that this fixes the problem with superclass resources which use @Timed annotations on Dropwizard 0.9.1.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM