ברוכים הבאים למדריך ג'אווה ג'רסי. לאחרונה התחלתי לעבוד על פרויקט שירות רשת Restful באמצעות הגרסה המסגרת JAX-RS Jersey.
מהו מסגרת ג'אווה ג'רסי?
פרויקט ג'אווה ג'רסי מעקב אחר ממשק ה- JAX-RS, אשר משמש ליצירת שירותי רשת Restful בג'אווה.
1. מי צריך להשתמש במדריך זה?
המדריך מיועד למתכנתי ג'אווה המעוניינים לפתח ולהטמיע שירותי רשת Restful באמצעות ממשק ה- JAX-RS API ו-JAXB.
2. דרישות מוקדמות
הטווח של המדריך הוא להשתמש ב- Jersey API ליצירת שירותי רשת Restful ולקרוא לשירות הרשת באמצעות תוכנית לקוח ג'אווה ולבדוק את השירות באמצעות הכלי. נדרשת הבנה בסיסית של ג'אווה, שירותי רשת, XML, Maven, ושרתי אפליקציות כלשהם (JBoss/Tomcat) כדי להבין את המדריך בקלות.
3. תוכנות וכלים
- גרסת JDK 1.8.0_131
- Apache Maven 3.5.3
- Mac OS X 10.13.4
- Tomcat 8.5.16
- Eclipse Java EE IDE Oxygen 4.7.3
יצירת פרויקט Maven ל-Jersey ב-Eclipse
יש ליצור "Dynamic Web Project" ב-Eclipse ולהמיר אותו לפרויקט Maven. זה יספק לנו פרויקט בסיסי של יישום אינטרנט המבוסס על Maven. ניתן לציין GroupId כ-com.journaldev.jersey
ו-ArtifactId כ-my-jersey-project
, אך ניתן גם לציין כל שם אחר לפי הדרכך. לאחר התפתחות הפרויקט, מבנה הפרויקט ייראה כמו בתמונה למטה.
הסבר על פרויקט שירות רשת Jersey ב-Java
1. pom.xml: פרטי התצורה של הפרויקט, שים לב להתלויות jersey שסופקו, פרטים נוספים הם רגילים עבור כל פרויקט Maven דומה.
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.jersey</groupId>
<artifactId>my-jersey-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.14</version>
</dependency>
</dependencies>
<build>
<finalName>My-Jersey-Project</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. EmpRequest.java: Java Bean עבור אובייקט הבקשה. הדבר החשוב לשים לב אליו כאן הוא האנוטציה @XmlRootElement
למיפוי המחלקה לאלמנט XML.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empRequest")
public class EmpRequest {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3. EmpResponse.java: Java Bean עבור אובייקט התגובה.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "empResponse")
public class EmpResponse {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4. ErrorResponse.java: Java Bean שיישלח כתגובה במקרה של חריגה.
package com.journaldev.model;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "errorResponse")
public class ErrorResponse {
private String errorCode;
private int errorId;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public int getErrorId() {
return errorId;
}
public void setErrorId(int errorId) {
this.errorId = errorId;
}
}
5. EmpNotFoundException.java: מחלקת חריגה רגילה המשולכת בשירות האינטרנט.
package com.journaldev.exception;
public class EmpNotFoundException extends Exception {
private static final long serialVersionUID = 4351720088030656859L;
private int errorId;
public int getErrorId() {
return errorId;
}
public EmpNotFoundException(String msg, int errorId) {
super(msg);
this.errorId = errorId;
}
public EmpNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}
6. web.xml: תיאור ההטבעה עבור שירות האינטרנט. כל בקשה עם URI https://<HOST>:<PORT>/My-Jersey-Project/rest/*
תעובד על ידי סרבל Jersey ServletContainer. ערך ה-init-param שנשלח עבור "com.sun.jersey.config.property.packages" מגדיר את החבילה שבה יחפש jersey עבור מחלקות שירות האינטרנט. ערכו חייב להפנות למחלקות המשאבים שלך. הוא גם מחפש אחר מחלקות המשאבים בתתי החבילות.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns="https://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>My Jersey Project</display-name>
<!-- Jersey Servlet configurations -->
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.journaldev</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- Jersey Servlet configurations -->
</web-app>
7. EmpRouter.java: מחלקת משאב המטפלת בסוגי בקשות שונות.
- @Path(“/emp”) – כל הבקשות עם URI
https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/
יעובדו על ידי מחלקת המשאב הזו. - @Path("/getEmp") – כל הבקשות עם URI
https://<HOST>:<PORT>/My-Jersey-Project/rest/emp/getEmp
יעובדו על ידי שיטה זו. - @POST – האישון הזה מגדיר שהשיטה HTTP שמשתמשת צריכה להיות POST. ערכים אפשריים נוספים הם @GET, @PUT, @DELETE
- @Consumes(MediaType.APPLICATION_XML) – השיטה מקבלת אלמנט XML
- @Produces(MediaType.APPLICATION_XML) – השיטה מחזירה אלמנט XML
package com.journaldev.router;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBElement;
@Path("/emp")
public class EmpRouter {
@POST
@Path("/getEmp")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response getEmp(JAXBElement<EmpRequest> empRequest)
throws EmpNotFoundException {
EmpResponse empResponse = new EmpResponse();
if (empRequest.getValue().getId() == 1) {
empResponse.setId(empRequest.getValue().getId());
empResponse.setName(empRequest.getValue().getName());
} else {
throw new EmpNotFoundException("Wrong ID", empRequest.getValue()
.getId());
}
return Response.ok(empResponse).build();
}
}
8. EmpNotFoundExceptionMapper.java: מחלקת ממפה חריגה שמטמפת EmpNotFoundException לאובייקט מענה. על המחלקה לכלול את האנוטציה @Provider. המחלקה צריכה להיות בחבילה שסופקה עבור מחלקות משאב ב web.xml. המימוש של השיטה toResponse()
יוצר את אובייקט השגיאה ומגדיר אותו כישות בתוך אובייקט מענה עם סטטוס INTERNAL_SERVER_ERROR.
package com.journaldev.exceptionmapper;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import com.journaldev.exception.EmpNotFoundException;
import com.journaldev.model.ErrorResponse;
@Provider
public class EmpNotFoundExceptionMapper implements
ExceptionMapper<EmpNotFoundException> {
public EmpNotFoundExceptionMapper() {
}
public Response toResponse(
EmpNotFoundException empNotFoundException) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrorId(empNotFoundException.getErrorId());
errorResponse.setErrorCode(empNotFoundException.getMessage());
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
errorResponse).type(
MediaType.APPLICATION_XML).build();
}
}
השירות שלנו מוכן, רק צריך לבנות אותו כדי ליצור את קובץ ה-WAR ולהפעיל אותו בשרת היישום.
דוגמה לקליינט של Jersey
ניתן להשתמש בקליינט של Jersey כדי לקרוא לשירות האינטרנט שלנו ולקבל תגובה באופן תכנותי. EmpClient.java: זוהי תכנית דוגמה בשפת ג'אווה דרכה אנו קוראים לשירות האינטרנט שלנו. אנו משתמשים ב- Jersey Client API כדי לקרוא לשירות ובהתאם למצב התגובה אנו מנתחים את יישות התגובה למחלקת EmpResponse או למחלקת ErrorResponse.
package com.journaldev.client;
import javax.ws.rs.core.MediaType;
import com.journaldev.model.EmpRequest;
import com.journaldev.model.EmpResponse;
import com.journaldev.model.ErrorResponse;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
public class EmpClient {
/**
* @param args
*/
public static void main(String[] args) {
String uri = "https://localhost:8080/My-Jersey-Project/rest/emp/getEmp";
EmpRequest request = new EmpRequest();
// הגדרת id כ-1 למענה תקין
request.setId(2);
request.setName("PK");
try {
Client client = Client.create();
WebResource r = client.resource(uri);
ClientResponse response = r.type(MediaType.APPLICATION_XML).post(ClientResponse.class, request);
System.out.println(response.getStatus());
if (response.getStatus() == 200) {
EmpResponse empResponse = response.getEntity(EmpResponse.class);
System.out.println(empResponse.getId() + "::" + empResponse.getName());
} else {
ErrorResponse exc = response.getEntity(ErrorResponse.class);
System.out.println(exc.getErrorCode());
System.out.println(exc.getErrorId());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
תגובת הצלחה תגובת שגיאה
סיכום
בפוסט זה, למדנו כיצד ליצור שירות אינטרנט REST באמצעות Jersey API. גם בדקנו את הקליינט של Jersey לקריאת ה- REST APIs שלנו דרך תכנית ג'אווה.
ניתן לבדוק את קוד הפרויקט השלם בגיטהאב שלנו GitHub Repository.
Source:
https://www.digitalocean.com/community/tutorials/jersey-java-tutorial