嵌入式Tomcat的RestEasy不扫描控制器

时间:2017-11-09 07:35:12

标签: java rest tomcat servlets microservices

我使用RestEasy与嵌入式Tomcat导出可运行的jar文件,该文件部署了一些Rest API(仅用于测试,我不想使用SpringBoots)。 我在主入口点编写了一些代码来注册HttpServletDispatcher

public class Main {

public static void main(String[] args) throws Exception {
    try {
        new Main().run();
    } catch (Throwable t) {
        t.printStackTrace();
    }
}

    public void run() throws Exception {
        Tomcat tomcat = new Tomcat();
        tomcat.setPort(8080);

        Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath());
        String contextPath = "/";
        String appBase = ".";
        tomcat.getHost().setAppBase(appBase);
        tomcat.addWebapp(contextPath, appBase);

        Tomcat.addServlet(ctx, "rest-easy-servlet", new HttpServletDispatcher());
        ctx.addServletMapping("/*", "rest-easy-servlet");
        tomcat.start();
        tomcat.getServer().await();
    }
}

服务器启动成功,但没有任何Rest API。当访问路径localhost:8080 / users / hello时,我在日志中遇到错误。

  

2017年11月9日下午2:21:22 org.apache.coyote.AbstractProtocol start INFO:   启动ProtocolHandler [" http-nio-8080"] 2017年11月9日下午2:21:30   org.jboss.resteasy.core.ExceptionHandler严重:执行失败   javax.ws.rs.NotFoundException:无法找到完整路径的资源:   http://localhost:8080/users/hello at   org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73)     在   org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:48)     在   org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:444)     在   org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:234)     在   org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:171)     在   org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)     在   org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)     在   org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)     在javax.servlet.http.HttpServlet.service(HttpServlet.java:790)at   org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)     在   org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)     在   org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)     在   org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)     在   org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)     在   org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)     在   org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)     在   org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)     在   org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)     在   org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)     在   org.apache.coyote.AbstractProtocol $ AbstractConnectionHandler.process(AbstractProtocol.java:673)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.doRun(NioEndpoint.java:1500)     在   org.apache.tomcat.util.net.NioEndpoint $ SocketProcessor.run(NioEndpoint.java:1456)     在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:617)     在   org.apache.tomcat.util.threads.TaskThread $ WrappingRunnable.run(TaskThread.java:61)     在java.lang.Thread.run(Thread.java:745)

我认为RestEasy没有任何信号可以扫描其组件。请帮我扫描RestEasy组件的方法,或者像使用web.xml一样注册RestEasy的方法

2 个答案:

答案 0 :(得分:2)

使用嵌入式Tomcat时,不会自动扫描资源和提供程序。您必须使用逗号分隔值在Application子类或resteasy.resources上下文参数中手动注册它们。

首先,确保项目中具有以下依赖项:

<properties>
    <tomcat.version>8.5.23</tomcat.version>
    <resteasy.version>3.1.4.Final</resteasy.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-core</artifactId>
        <version>${tomcat.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
</dependencies>

创建JAX-RS资源类:

@Path("hello")
public class HelloWorldResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response helloWorld() {
        return Response.ok("Hello World!").build();
    }
}

创建一个Application子类并注册上面创建的资源类:

public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        return Collections.singleton(HelloWorldResource.class);
    }
}

创建一个类来启动Tomcat并部署您的应用程序:

public class Launcher {

    private static final String RESTEASY_SERVLET_NAME = "resteasy-servlet";

    public static void main(String[] args) throws Exception {
        new Launcher().start();
    }

    void start() throws Exception {

        String port = System.getenv("PORT");
        if (port == null || port.isEmpty()) {
            port = "8080";
        }

        String contextPath = "/api";
        String appBase = ".";

        Tomcat tomcat = new Tomcat();
        tomcat.setPort(Integer.valueOf(port));
        tomcat.getHost().setAppBase(appBase);

        Context context = tomcat.addContext(contextPath, appBase);
        context.addApplicationListener(ResteasyBootstrap.class.getName());
        Tomcat.addServlet(context, RESTEASY_SERVLET_NAME, new HttpServletDispatcher());
        context.addParameter("javax.ws.rs.Application", MyApplication.class.getName());
        context.addServletMappingDecoded("/*", RESTEASY_SERVLET_NAME);

        tomcat.start();
        tomcat.getServer().await();
    }
}

最后添加Maven Shade插件以创建可执行JAR,其中mainClass属性引用上述create类:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.4.3</version>
            <configuration>
                <finalName>tomcat-embedded-example-${project.version}</finalName>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>com.example.Launcher</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

要编译并运行该应用程序,请按以下步骤操作:

  • 打开命令行窗口或终端。
  • 导航到pom.xml所在的项目的根目录。
  • 编译项​​目:mvn clean compile
  • 打包应用程序:mvn package
  • 查看目标目录。您应该看到一个包含以下名称或类似名称的文件:tomcat-embedded-sample-1.0-SNAPSHOT.jar
  • 转到目标目录。
  • 执行JAR:java -jar tomcat-embedded-example-1.0-SNAPSHOT.jar
  • 该应用程序位于http://localhost:8080/api/hello

查看更多:

答案 1 :(得分:0)

您的Rest控制器可能无法自动检测/扫描 - 如您所建议的那样。您可以尝试manually register your class公开&#34; users /&#34;资源。