在 Java Servlet Restful 客户端教程中,我们使用 JAX-RS 在 Java Servlet 中创建 Restful 客户端。
用于 Restful Web 服务的 Java API(JAX-RS)是 Java API 规范,它提供了根据代表性状态转移(REST)架构模式创建 Web 服务的支持。
Jersey 是 Java Restful Web 服务框架和 JAX-RS 参考实现。
Servlet 是 Java 类,可响应特定类型的网络请求-最常见的是 HTTP 请求。 Java servlet 用于创建 Web 应用。 它们在 servlet 容器(例如 Tomcat 或 Jetty)中运行。 现代 Java Web 开发使用在 servlet 之上构建的框架。
Java Servlet 应用
以下 Web 应用向api.randomuser.me站点创建一个请求,该站点是一个随机用户生成器。
Java servlet 使用ClientBuilder创建一个Client,这是用于构建和执行客户端请求以使用返回的响应的流畅 API 的主要入口点。
$ tree.├── nb-configuration.xml├── pom.xml└── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── model │ │ │ ├── Location.java │ │ │ ├── Name.java │ │ │ ├── Person.java │ │ │ └── PersonsList.java │ │ ├── service │ │ │ └── PersonService.java │ │ └── web │ │ └── MyServlet.java │ ├── resources │ └── webapp │ ├── index.html │ ├── META-INF │ │ └── context.xml │ ├── show.jsp │ └── WEB-INF └── test └── java
这是项目结构。
pom.xml
<?xml version="1.0" encoding="UTF-8"?><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>com.zetcode</groupId> <artifactId>JavaServletRestClient</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>JavaServletRestClient</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>2.25.1</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>2.22</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </build></project>
这是 Maven POM 文件。 我们有四个工件:用于 servlet 的javax.servlet-api,用于标准 JSP 标签库的jstl,用于 RESTFul 核心客户端实现的jersey-client和用于 JSON / Java Bean 数据绑定的jersey-media-json-jackson。
context.xml
<?xml version="1.0" encoding="UTF-8"?><Context path="/JavaServletRestClient"/>
在 Tomcat context.xml文件中,我们定义了上下文路径。 它是 Web 应用的名称。
在该应用中,我们有三个 bean。 这些 bean 将被响应中的数据填充。
Location.java
package com.zetcode.model;public class Location { private String street; private String city; private String state; private String postcode; public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getPostcode() { return postcode; } public void setPostcode(String postcode) { this.postcode = postcode; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(street).append(" ") .append(city).append(" ") .append(state).append(" ") .append(postcode); return sb.toString(); }}Location存储用户的地址。
Name.java
package com.zetcode.model;public class Name { private String first; private String last; private String title; public String getFirst() { return first; } public void setFirst(String firstName) { first = firstName; } public String getLast() { return last; } public void setLast(String lastName) { last = lastName; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(title).append(" ").append(first) .append(" ").append(last); return sb.toString(); } }Name存储用户名详细信息。
Person.java
package com.zetcode.model;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;@JsonIgnoreProperties(ignoreUnknown = true)public class Person { private Name name; private Location location; private String email; private String gender; public void setName(Name name) { this.name = name; } public Name getName() { return name; } public Location getLocation() { return location; } public void setLocation(Location location) { this.location = location; } public void setEmail(String email) { this.email = email; } public String getEmail() { return email; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Name: ").append(name) .append("Address: ").append(location) .append("Email ").append(email) .append("Gender: ").append(gender); return sb.toString(); }}Person类存储有关用户的数据,包括姓名,地址,电子邮件和性别。
@JsonIgnoreProperties(ignoreUnknown = true)
使用@JsonIgnoreProperties批注,我们告诉 Jackson 忽略Person中未列出的属性。
PersonsList.java
package com.zetcode.model;import com.fasterxml.jackson.annotation.JsonIgnoreProperties;import java.util.List;@JsonIgnoreProperties(ignoreUnknown = true)public class PersonsList { List<Person> results; public List<Person> getResults() { return results; } public void setResults(List<Person> result) { results = result; }}这是Person对象的列表。 Web 服务使用数据填充此列表。
MyServlet.java
package com.zetcode.web;import com.zetcode.model.Person;import com.zetcode.service.PersonService;import java.io.IOException;import java.util.List;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); List<Person> people = PersonService.fetchPeople(0, 50); request.setAttribute("people", people); request.getRequestDispatcher("show.jsp").forward(request, response); }}MyServlet Servlet 调用PersonService.fetchPeople(),它返回Person对象的列表。 该列表将作为属性存储,并且处理将分派到show.jsp页面。 JSP 页面呈现Person对象的列表。
PersonService.java
package com.zetcode.service;import com.zetcode.model.Person;import com.zetcode.model.PersonsList;import java.util.List;import javax.ws.rs.client.ClientBuilder;import javax.ws.rs.client.WebTarget;import javax.ws.rs.core.MediaType;public class PersonService { private static WebTarget resource = ClientBuilder.newBuilder() .build().target("https://api.randomuser.me/"); public static List<Person> fetchPeople(int offset, int num) { PersonsList res = resource.queryParam("seed", 1) .queryParam("results", num).queryParam("page", 1) .request(MediaType.APPLICATION_JSON).get(PersonsList.class); return res.getResults(); } }PersonService包含用于在api.randomuser.me Web 服务上执行查询的fetchPeople()方法。 该服务随机返回用户对象。
private static WebTarget resource = ClientBuilder.newBuilder() .build().target("https://api.randomuser.me/");使用ClientBuilder创建一个 Web 资源目标。 api.randomuser.me网站随机返回用户列表。
public static List<Person> fetchPeople(int offset, int num) { PersonsList res = resource.queryParam("seed", 1) .queryParam("results", num).queryParam("page", 1) .request(MediaType.APPLICATION_JSON).get(PersonsList.class); return res.getResults();} 我们向网络资源发送查询; 数据存储在PersonsList中。
index.html
<!DOCTYPE html><html> <head> <title>Home Page</title> <meta charset="UTF-8"> </head> <body> <a href="MyServlet">List people</a> </body></html>
这是主页。 它包含一个调用MyServlet的链接。
show.jsp
<%@page contentType="text/html" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Show people</title> </head> <body> <table> <thead> <tr> <th>Title</th> <th>First name</th> <th>Last name</th> <th>Street</th> <th>City</th> <th>State</th> <th>Postcode</th> <th>Email</th> <th>Gender</th> </tr> </thead> <tbody> <c:forEach var="per" items="{people}"> <tr> <td><c:out value="{per.name.title}"/></td> <td><c:out value="{per.name.first}"/></td> <td><c:out value="{per.name.last}"/></td> <td><c:out value="{per.location.street}"/></td> <td><c:out value="{per.location.city}"/></td> <td><c:out value="{per.location.state}"/></td> <td><c:out value="{per.location.postcode}"/></td> <td><c:out value="{per.email}"/></td> <td><c:out value="{per.gender}"/></td> </tr> </c:forEach> </tbody> </table> </body> </html>
show.jsp页面使用 JSTL 库中的c:forEach和c:out标签在 HTML 表中显示数据。
在本教程中,我们向 Web 服务创建了一个 JAX-RS 客户端请求,该请求会随机生成用户。 该请求是从 Java Servlet 发送的。
您可能也对以下相关教程感兴趣: Java servlet Log4j 教程, Java servlet JSON 教程, Java Servlet PDF 教程, Java Servlet 复选框教程,Java Servlet 图表教程, Java Servlet HTTP 标头或 Java 教程。
