【问题标题】:How to embed Jetty and Jersey into my Java application如何将 Jetty 和 Jersey 嵌入到我的 Java 应用程序中
【发布时间】:2013-07-31 00:07:06
【问题描述】:

所以我正在尝试将 jetty 嵌入到我的 Web 应用程序中,这样如果我将其打包为 jar,则有人可以运行 jar 文件而不必担心配置服务器。但是,我在设置我的主类时遇到了一些问题,以便码头可以访问我的资源类。我看过教程,但他们并没有给我我想要的东西。这是我到目前为止所拥有的。

package pojo;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class Main {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
        context.setContextPath("/");
        ServletHolder h = new ServletHolder(new DefaultServlet());
        h.setInitParameter("javax.ws.rs.Application","resources.DBCollection");
        context.addServlet(h, "/*");
        server.setHandler(context);
        server.start();
        server.join();
    }
}

我正在尝试将其映射到此类:

package resources;


import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;

import pojo.Party;

@Path("/parties")
public class DBCollection {

    @Context
    UriInfo url;

    @Context
    Request request;

    String name;

    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public List<Party> getAllParties() throws Exception
    {
        List<Party> list = new ArrayList<Party>();
        list.addAll(DBConnection.getPartyCollection().values());
        return list;
    }

    @GET
    @Path("count")
    @Produces(MediaType.TEXT_PLAIN)
    public String getPartyCount() throws Exception
    {
        return String.valueOf(DBConnection.getPartyCollection().size());
    }

    @Path("{party}")
    public DBResource getParty(@PathParam("party")String party)
    {
        return new DBResource(url,request,party);
    }
}

这是我的 POM 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>PartyAPI</groupId>
    <artifactId>PartyAPIMaven</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.codahale.metrics</groupId>
            <artifactId>metrics-core</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.17.1</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.0.0.RC0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.0.0.RC0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlets</artifactId>
            <version>9.0.0.RC0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.6.0-SNAPSHOT</version>
        </dependency>

    </dependencies>
    <repositories>
        <repository>
            <id>oss.sonatype.org</id>
            <name>OSS Sonatype Staging</name>
            <url>https://oss.sonatype.org/content/groups/staging</url>
        </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.6</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <manifestEntries>
                                        <Main-Class>com.resteasy.Star.Main</Main-Class>

                                    </manifestEntries>

                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

【问题讨论】:

    标签: java maven jetty embedded-jetty


    【解决方案1】:

    一些事情。

    1. Jetty 9.0.0.RC0 是一个旧的、尚未稳定的候选版本,请考虑升级到稳定的最终版本,例如9.0.4.v20130625
    2. 您需要将 Jax RS 类连接到 servlet api 的东西。通常通过 Servlet 或使用您选择的库进行某种初始化来完成。 (在你的情况下是泽西岛)

    在您的示例中,您只设置了一个 DefaultServlet 来提供静态文件,没有配置任何内容来使用您的 DBCollection 对象。

    对于 Jersey,您需要配置 org.glassfish.jersey.servlet.ServletContainer 并在您选择的上下文中设置其 servlet 映射。

    示例:

    package com.example;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.servlet.DefaultServlet;
    import org.eclipse.jetty.servlet.ServletContextHandler;
    import org.eclipse.jetty.servlet.ServletHolder;
    
    public class Main
    {
        public static void main(String[] args)
        {
            Server server = new Server(8080);
    
            ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
            context.setContextPath("/");
            server.setHandler(context);
    
            ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/webapi/*");
            jerseyServlet.setInitOrder(1);
            jerseyServlet.setInitParameter("jersey.config.server.provider.packages","com.example");
    
            ServletHolder staticServlet = context.addServlet(DefaultServlet.class,"/*");
            staticServlet.setInitParameter("resourceBase","src/main/webapp");
            staticServlet.setInitParameter("pathInfoOnly","true");
    
            try
            {
                server.start();
                server.join();
            }
            catch (Throwable t)
            {
                t.printStackTrace(System.err);
            }
        }
    }
    

    此示例将 jersey 提供的 ServletContainer 添加到 ServletContextHandler 中,Jetty 使用该 ServletContextHandler 根据传入的请求查找要执行的操作。然后它添加 DefaultServlet 来处理 Jersey 不处理的任何内容请求(例如静态内容)

    【讨论】:

    • 所以当我输入 localhost:8111/webapi/parties 时出现 500 错误(注意:我将端口更改为 8111,因为我遇到了 NetBind 异常),我该如何解决(没有堆栈strace 被打印出来)。另外,我找不到 javadocs,您介意解释一下 setInitParameter 的作用以及“静态”内容与球衣内容的含义
    • 静态内容是非动态的内容,无论谁请求它都保持静态(例如图像、javascript、css 等)。 Jersey 资源属于动态内容方案。您的代码生成的内容将发送回最终用户(浏览器)。至于错误 500,请使用生成的堆栈跟踪更新您的问题。也知道我无法评论泽西岛的细节(因为我真的不了解它们。我是 Jetty 开发人员)
    • 我没有得到堆栈跟踪 :(,我假设我可以从主类运行程序?还是我必须从项目目录运行?这有意义吗
    • 注意,我没有得到堆栈跟踪的事实仍然与原始问题有关。我只是收到一个 500 错误原因:请求失败。没有堆栈跟踪
    • 我写了一篇博客文章/教程,部分基于您的讨论 - wp.me/p48ema-6f。希望你觉得它有用。
    【解决方案2】:

    如果您想以编程方式完全管理 DBCollection 资源的生命周期(例如,您自己实例化它,进行一些设置/初始化等),而不是让 Jersey 为您创建实例,您可以使用 @987654322 @像这样:

    ServletContextHandler sch = new ServletContextHandler();
    sch.setContextPath("/xxx");
    
    TheResource resource = new TheResource();
    ResourceConfig rc = new ResourceConfig();
    rc.register(resource);
    
    ServletContainer sc = new ServletContainer(rc);
    ServletHolder holder = new ServletHolder(sc);
    sch.addServlet(holder, "/*");
    
    Server server = new Server(port);
    server.setHandler(sch);
    server.start();
    server.join();
    

    注意TheResource resource = new TheResource(); 这一行。在这里,我们创建了自己的 TheResource 实例,现在我们可以随意操作它了。

    【讨论】:

      猜你喜欢
      • 2022-07-08
      • 2011-03-03
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 2013-11-01
      • 2011-11-22
      相关资源
      最近更新 更多