1. Overview
1.概述
Jersey is an open-source framework for developing RESTFul Web Services.
Jersey是一个用于开发RESTFul Web服务的开源框架。
As well as serving as the JAX-RS reference implementation it also includes a number of extensions to further simplify web application development.
除了作为JAX-RS的参考实现之外,它还包括一些扩展,以进一步简化Web应用的开发。
In this tutorial, we’ll create a small example application that uses the Model-View-Controller (MVC) extension offered by Jersey.
在本教程中,我们将创建一个使用Jersey提供的Model-View-Controller(MVC)扩展的小型示例应用程序。
To learn how to create an API with Jersey, check out this write-up here.
要了解如何使用Jersey创建API,请查看这里的文章。
2. MVC in Jersey
2.泽西岛的MVC
Jersey contains an extension to support the Model-View-Controller (MVC) design pattern.
Jersey包含一个支持Model-View-Controller(MVC)设计模式的扩展。
First of all, in the context of Jersey components, the Controller from the MVC pattern corresponds to a resource class or method.
首先,在Jersey组件的背景下,MVC模式中的控制器对应于资源类或方法。
Likewise, the View corresponds to a template bound to a resource class or method. Finally, the model represents a Java object returned from a resource method (Controller).
同样地,视图对应于一个绑定到资源类或方法的模板。最后,模型代表一个从资源方法(Controller)返回的Java对象。
To use the capabilities of Jersey MVC in our application, we first need to register the MVC module extension that we wish to use.
为了在我们的应用程序中使用Jersey MVC的功能,我们首先需要注册我们想要使用的MVC模块扩展。
In our example, we’re going to use the popular Java template engine Freemarker. This is one of the rendering engines supported by Jersey out of the box along with Mustache and standard Java Server Pages (JSP).
在我们的示例中,我们将使用流行的Java模板引擎Freemarker。这是Jersey开箱即支持的渲染引擎之一,此外还有Mustache和标准Java服务器页面(JSP)。
For more information about how MVC works, please refer to this tutorial.
关于MVC如何工作的更多信息,请参考这个教程。
3. Application Setup
3.应用设置
In this section, we’ll start by configuring the necessary Maven dependencies in our pom.xml.
在本节中,我们将首先在pom.xml.中配置必要的Maven依赖项。
Then, we’ll take a look at how to configure and run our server using a simple embedded Grizzly server.
然后,我们将看看如何使用一个简单的嵌入式Grizzly服务器来配置和运行我们的服务器。
3.1. Maven Dependencies
3.1.Maven的依赖性
Let’s start by adding the Jersey MVC Freemarker extension.
让我们从添加Jersey MVC Freemarker扩展开始。
We can get the latest version from Maven Central:
我们可以从Maven中心获得最新版本。
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-mvc-freemarker</artifactId>
<version>2.27</version>
</dependency>
We’re also going to need the Grizzly servlet container.
我们还将需要Grizzly servlet容器。
Again we can find the latest version in Maven Central:
同样,我们可以在Maven中心找到最新版本。
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-servlet</artifactId>
<version>2.27</version>
</dependency>
3.2. Configuring the Server
3.2.配置服务器
To make use of the Jersey MVC templating support in our application we need to register the specific JAX-RS features provided by the MVC modules.
为了在我们的应用程序中使用Jersey MVC模板支持,我们需要注册MVC模块所提供的特定JAX-RS功能。
With this in mind, we define a custom resource configuration:
考虑到这一点,我们定义一个自定义的资源配置。
public class ViewApplicationConfig extends ResourceConfig {
public ViewApplicationConfig() {
packages("com.baeldung.jersey.server");
property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
register(FreemarkerMvcFeature.class);;
}
}
In the above example we configure three items:
在上述例子中,我们配置了三个项目。
- First, we use the packages method to tell Jersey to scan the com.baeldung.jersey.server package for classes annotated with @Path. This will register our FruitResource
- Next, we configure the base path in order to resolve our templates. This tells Jersey to look in the /src/main/resources/templates/freemarker for Freemarker templates
- Finally, we register the feature that handles the Freemarker rendering via the FreemarkerMvcFeature class
3.3. Running the Application
3.3.运行应用程序
Now let’s look at how to run our web application. We’ll use the exec-maven-plugin to configure our pom.xml to execute our embedded web server:
现在我们来看看如何运行我们的网络应用。我们将使用exec-maven-plugin来配置我们的pom.xml以执行我们的嵌入式Web服务器。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<mainClass>com.baeldung.jersey.server.http.EmbeddedHttpServer</mainClass>
</configuration>
</plugin>
Let’s now compile and run our application using Maven:
现在让我们用Maven编译并运行我们的应用程序。
mvn clean compile exec:java
...
Jul 28, 2018 6:21:08 PM org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Application started.
Try out http://localhost:8082/fruit
Stop the application using CTRL+C
Go to the browser URL – http://localhost:8080/fruit. Voila, the “Welcome Fruit Index Page!” is displayed.
进入浏览器的URL – http://localhost:8080/fruit。瞧,”欢迎水果索引页!”就显示出来了。
4. MVC Templates
4.MVC模板
In Jersey, the MVC API consists of two classes to bind the model to the view namely Viewable and @Template.
在Jersey中,MVC API包括两个将模型与视图绑定的类,即Viewable和@Template。
In this section we’ll explain three different ways of linking templates to our view:
在本节中,我们将解释将模板链接到我们的视图的三种不同方式。
- Using the Viewable class
- Using the @Template annotation
- How to handle errors with MVC and pass them to a specific template
4.1. Using Viewable in a Resource Class
4.1.在资源类中使用Viewable
Let’s start by looking at Viewable:
让我们先来看看Viewable。
@Path("/fruit")
public class FruitResource {
@GET
public Viewable get() {
return new Viewable("/index.ftl", "Fruit Index Page");
}
}
In this example, the FruitResource JAX-RS resource class is the controller. The Viewable instance encapsulates the referenced data model which is a simple String.
在这个例子中,FruitResource JAX-RS资源类是控制器。Viewable实例封装了引用的数据模型,这是一个简单的String。
Furthermore, we also include a named reference to the associated view template – index.ftl.
此外,我们还包括一个对相关视图模板的命名引用–index.ftl。
4.2. Using @Template on a Resource Method
4.2.在一个资源方法上使用@Template
There’s no need to use Viewable every time we want to bind a model to a template.
我们没有必要每次都使用Viewable将模型绑定到模板上。
In this next example, we’ll simply annotate our resource method with @Template:
在接下来的例子中,我们将简单地用@Template来注释我们的资源方法。
@GET
@Template(name = "/all.ftl")
@Path("/all")
@Produces(MediaType.TEXT_HTML)
public Map<String, Object> getAllFruit() {
List<Fruit> fruits = new ArrayList<>();
fruits.add(new Fruit("banana", "yellow"));
fruits.add(new Fruit("apple", "red"));
fruits.add(new Fruit("kiwi", "green"));
Map<String, Object> model = new HashMap<>();
model.put("items", fruits);
return model;
}
In this example, we’ve used the @Template annotation. This avoids wrapping our model directly in a template reference via Viewable and makes our resource method more readable.
在这个例子中,我们使用了@Template注解。这避免了通过Viewable将我们的模型直接包裹在模板引用中,使我们的资源方法更易读。
The model is now represented by the return value of our annotated resource method – a Map<String, Object>. This is passed directly to the template all.ftl which simply displays our list of fruit.
该模型现在由我们注释的资源方法的返回值表示–一个Map<String, Object>。这被直接传递给模板all.ftl,它只是显示我们的水果列表。
4.3. Handling Errors with MVC
4.3.用MVC处理错误
Now let’s take a look at how to handle errors using the @ErrorTemplate annotation:
现在让我们来看看如何使用@ErrorTemplate注解来处理错误。
@GET
@ErrorTemplate(name = "/error.ftl")
@Template(name = "/named.ftl")
@Path("{name}")
@Produces(MediaType.TEXT_HTML)
public String getFruitByName(@PathParam("name") String name) {
if (!"banana".equalsIgnoreCase(name)) {
throw new IllegalArgumentException("Fruit not found: " + name);
}
return name;
}
Generally speaking, the purpose of the @ErrorTemplate annotation is to bind the model to an error view. This error handler will take care of rendering the response when an exception is thrown during the processing of a request.
一般来说,@ErrorTemplate注解的目的是将模型与错误视图绑定。这个错误处理程序将负责在处理请求时抛出的异常中呈现响应。
In our simple Fruit API example if no errors occur during processing then the named.ftl template is used to render the page. Otherwise, if an exception is raised then the error.ftl template is shown to the user.
在我们简单的Fruit API例子中,如果在处理过程中没有发生错误,那么named.ftl模板被用来渲染页面。否则,如果出现异常,那么error.ftl模板将显示给用户。
In this case, the model is the thrown exception itself. This means from within our template we can call methods directly on the exception object.
在这种情况下,模型就是被抛出的异常本身。这意味着在我们的模板中我们可以直接调用异常对象的方法。
Let’s take a quick look at a snippet from our error.ftl template to highlight this:
让我们快速看一下我们的error.ftl模板的一个片段,以强调这一点。
<body>
<h1>Error - ${model.message}!</h1>
</body>
In our final example, we’ll take a look at a simple unit test:
在我们的最后一个例子中,我们将看一下一个简单的单元测试。
@Test
public void givenGetFruitByName_whenFruitUnknown_thenErrorTemplateInvoked() {
String response = target("/fruit/orange").request()
.get(String.class);
assertThat(response, containsString("Error - Fruit not found: orange!"));
}
In the above example, we use the response from our fruit resource. We check the response contains the message from the IllegalArgumentException that was thrown.
在上面的例子中,我们使用了来自我们的水果资源的响应。我们检查响应是否包含抛出的IllegalArgumentException的信息。
5. Conclusion
5.总结
In this article, we’ve explored the Jersey framework MVC extension.
在这篇文章中,我们已经探讨了Jersey框架的MVC扩展。
We started by introducing how MVC works in Jersey. Next, we took a look at how to configure, run and set up an example web application.
我们首先介绍了MVC在Jersey中是如何工作的。接下来,我们看了一下如何配置、运行和设置一个Web应用程序的例子。
Finally, we looked at three ways of using MVC templates with Jersey and Freemarker and how to handle errors.
最后,我们看了用Jersey和Freemarker使用MVC模板的三种方式以及如何处理错误。
As always, the full source code of the article is available over on GitHub.
一如既往,该文章的完整源代码可在GitHub上获得。