gpt4 book ai didi

java - Jersey框架如何在REST中实现JAX-RS API?

转载 作者:行者123 更新时间:2023-11-29 06:52:00 29 4
gpt4 key购买 nike

我知道这个问题上有很多答案,但是我仍然对JAX-RS API(规范)和Jersey框架(参考实现)之间的差异感到困惑。

我读到:

Jersey框架基本上使用com.sun.jersey.spi.container.servlet.ServletContainer servlet拦截所有传入的请求。正如我们在项目web.xml中配置的那样,所有传入的rest请求都应由该servlet处理。有一个用jersey servlet配置的init-param,用于查找您的REST服务类。 REST服务类不是Servlet,并且不需要像在代码中那样扩展HttpServlet。这些REST服务类是简单的POJO,带有注解,用于告知jersey框架有关路径,消耗,生产等不同属性的信息。当您从服务方法返回时,jersey负责将这些对象编组到已定义的“ PRODUCES” responseType中并进行编写。在客户端流上

我的问题是当您说:“ jersey负责将已定义的'PRODUCES'responseType中的对象编组并写入客户端流中”,这是jersey的意思,什么是处理对象的实际类或库。

当我看到球衣是处理JAX-RS API规范的引擎时,我感到困惑。有人可以解释这句话中“球衣”一词的确切含义吗?在Jersey的哪个实际班级上处理Jersey的请求和响应?

最佳答案

规范和实现的概念实际上是非常基本的软件工程概念。您的规格是高级设计。为了帮助理解,我只是想出了一个非常简单的示例。

说我想拥有一个解析库。我知道我要如何使用它。唯一的问题是我不太擅长编写解析代码。因此,我创建了一个高级规范,并将实现外包。这是规范中的三个类。 myparsers-api.jar说,它们全部包含在一个“ API jar”中

public interface Parser {
String[] parse(String s);
}

public interface ParserFactory {
Parser getBySpaceParser();
Parser getByCommaParser();
}

public class ParserDepot {
private static ServiceLoader<ParserFactory> loader
= ServiceLoader.load(ParserFactory.class);

public static ParserFactory getDefaultParserFactory() {
final List<ParserFactory> factories = new ArrayList<>();
loader.forEach(factories::add);
if (factories.isEmpty()) {
throw new IllegalStateException("No ParserFactory found");
}
return factories.get(0);
}
}


因此,在这一点上,我实际上可以针对此jar进行编码。如果我要像现在在另一个项目中那样使用它,则该项目将可以正常编译。

ParserFactory factory = ParserDepot.getDefaultParserFactory();
Parser parser = factory.getBySpaceParser();
String[] tokens = parser.parse("Hello World");
System.out.println(Arrays.toString(tokens));


因此,即使没有该规范的实现,我仍然可以针对它进行编码,并针对它进行编译。但是,当我尝试实际运行程序时,由于没有实现,因此它将无法工作。您可以尝试运行此代码,并且会得到一个 IllegalStateException(如果您不熟悉此模式,请参见 the docs for ServiceLoader)。

因此,我将实施外包给一家名为Stack Overflow的公司。他们得到了myparsers-api.jar,需要给我一个实现。他们将需要实现一个 ParserFactory和几个 Parser。他们可能看起来像这样

public class SoByCommaParser implements Parser {
@Override
public String[] parse(String s) {
return s.split("\\s+,\\s+");
}
}

public class SoBySpaceParser implements Parser {
@Override
public String[] parse(String s) {
return s.split("\\s+");
}
}

public class SoParserFactory implements ParserFactory {
@Override
public Parser getBySpaceParser() {
return new SoBySpaceParser();
}

@Override
public Parser getByCommaParser() {
return new SoByCommaParser();
}
}


现在,Stack Overflow给了我一个罐子(例如so-myparsers-impl.jar),其中包含这三个类以及所需的META-INF / services文件(根据ServiceLoader模式),现在添加了so-myparsers-impl。 jar到我的项目并尝试再次运行它,该程序现在可以工作了,因为它已经实现了。

这正是JAX-RS规范的工作方式。它仅定义了其工作方式的高级设计。该设计中的类,接口和批注放置在“ API jar”中,就像将我的高级解析器放入jar中一样。实现不能更改这些类。所有属于JAX-RS规范(版本2.x)的类都放在一个jar javax.ws.rs-api中。您可以针对该jar进行编码,并且您的代码可以正常编译。但是没有什么可以使它“起作用”的。

您同时检出 the written specificationclasses defined by the specification,您会发现源代码中唯一包含的类是规范中提到的那些类。但是您应该注意的是,书面规范完全没有提及应如何实现。以下面的代码为例

@Path("/test")
public class TestResource {
@GET
public String get() {
return "Testing";
}
}

@ApplicationPath("/api")
public class MyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(TestResource.class);
return classes;
}
}


现在,规范指出,这就是我们在servlet容器中运行JAX-RS应用程序所需要的。这就是全部。它没有说明一切应该如何工作。这就是它设计工作的方式。

那么,在Java中是否存在一些我们不知道的神奇巫毒会导致该 Application类启动服务器,而一些使该 @Path带注释的类自动启动请求的局点。否。某些身体需要提供引擎。该引擎可能是20,000行代码,只是为了使上述代码按指定方式工作。

话虽这么说,泽西岛只是实现的名称。就像我将解析器实现外包给Stack Overflow一样; Jersey名称本身就是项目的名称,就像Hadoop是项目的名称一样。在这种情况下,项目是JAX-RS规范的实现。而且因为JAX-RS只是一个规范,所以它意味着任何人都可以实现它。如果愿意,可以编写自己的实现。只要它能按书面规范中的定义工作,您就可以说您的代码是JAX-RS的实现。不仅有泽西岛,还有其他。您还具有 RESTEasy,这是另一个实现。

至于Jersey如何实现引擎,这太广泛了。我能做的是为您提供有关幕后发生情况的高层次概述。

JAX-RS应用程序被定义为在servlet容器内部运行。如果您了解servlet容器和servlet规范,那么您将知道处理请求的唯一方法是编写 HttpServletFilter。因此,如果要实现JAX-RS,则需要能够通过 HttpServletFilter处理请求。您提到的 ServletContainer实际上是两者。因此对于泽西岛,就请求处理而言,这是进入泽西岛应用程序的“入口点”。它可以通过多种方式进行配置(我将研究工作留给了您)。

而且,如果您了解如何编写自己的servlet,那么您知道的只是一个 HttpServletRequestHttpServletResponse。您需要从那里弄清楚该做什么。从请求中获取请求信息,然后在响应中发回响应信息。泽西岛可以处理所有这一切。

如果您真的想深入了解发生了什么事情,您只需要从入口点 ServletContainer开始深入研究源代码。准备花几个月的时间对此做一个很好的了解。如果您期望如此,那么在一篇Stack Overflow帖子中就无法对此进行解释。

关于java - Jersey框架如何在REST中实现JAX-RS API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44966064/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com