Apache CXF พร้อม JAX-RS
ก่อนดำเนินการต่อในบทนี้เราคิดว่าคุณรู้วิธีเขียนเว็บเซอร์วิส RESTful ใน Java ฉันจะแสดงวิธีใช้ CXF กับ JAX-RS นี้ (Java API สำหรับ RESTful Web Services) เราจะสร้างบริการเว็บที่เก็บรายชื่อภาพยนตร์ล่าสุด เมื่อผู้ใช้ร้องขอภาพยนตร์เขาจะระบุ ID ภาพยนตร์ในคำขอของเขาเซิร์ฟเวอร์จะค้นหาภาพยนตร์และส่งคืนให้กับไคลเอ็นต์ ในกรณีที่ไม่สำคัญของเราเราจะส่งคืนชื่อภาพยนตร์ให้กับไคลเอนต์ไม่ใช่ไฟล์ MP4 ไบนารีจริง ให้เราเริ่มสร้างแอปพลิเคชัน JAX-RS
การประกาศองค์ประกอบภาพยนตร์
เราจะประกาศองค์ประกอบรูท XML ที่เรียกว่า Movie สำหรับจัดเก็บ id และชื่อของภาพยนตร์ที่กำหนด องค์ประกอบถูกประกาศในไฟล์ชื่อ Movie.java เนื้อหาของไฟล์แสดงที่นี่ -
//Movie.java
package com.tutorialspoint.cxf.jaxrs.movie;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Movie")
public class Movie {
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
หมายเหตุการใช้ XmlRootElement แท็กเพื่อประกาศองค์ประกอบ XML สำหรับไฟล์ Movieแท็ก ต่อไปเราจะสร้างบริการที่เก็บรายชื่อภาพยนตร์ไว้ในฐานข้อมูล
การสร้างฐานข้อมูลบริการภาพยนตร์
ในการจัดเก็บรายชื่อภาพยนตร์เราใช้ Java ที่ให้มา Mapที่เก็บคู่คีย์ - ค่า หากรายการมีขนาดใหญ่คุณจะใช้ที่เก็บฐานข้อมูลภายนอกซึ่งจะจัดการได้ง่ายขึ้น ในกรณีเล็กน้อยของเราเราจะจัดเก็บภาพยนตร์เพียงห้าเรื่องในฐานข้อมูลของเรา รหัสสำหรับคลาส MovieService ได้รับด้านล่าง -
//MovieService.java
package com.tutorialspoint.cxf.jaxrs.movie;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/movieservice/")
@Produces("text/xml")
public class MovieService {
long currentId = 123;
Map<Long, Movie> movies = new HashMap<>();
public MovieService() {
init();
}
@GET
@Path("/movie/{id}/")
public Movie getMovie(@PathParam("id") String id) {
long idNumber = Long.parseLong(id);
return movies.get(idNumber);
}
final void init() {
Movie c1 = new Movie();
c1.setName("Aquaman");
c1.setId(1001);
movies.put(c1.getId(), c1);
Movie c2 = new Movie();
c2.setName("Mission Imposssible");
c2.setId(1002);
movies.put(c2.getId(), c2);
Movie c3 = new Movie();
c3.setName("Black Panther");
c3.setId(1003);
movies.put(c3.getId(), c3);
Movie c4 = new Movie();
c4.setName("A Star is Born");
c4.setId(1004);
movies.put(c4.getId(), c4);
Movie c5 = new Movie();
c5.setName("The Meg");
c5.setId(1005);
movies.put(c5.getId(), c5);
}
}
โปรดทราบว่าเราใช้คำอธิบายประกอบสองรายการต่อไปนี้เพื่อระบุเส้นทาง URL สำหรับบริการภาพยนตร์ของเราและประเภทการส่งคืน -
@Path("/movieservice/")
@Produces("text/xml")
เราใช้คำอธิบายประกอบ @GET และ @Path เพื่อระบุ URL สำหรับคำขอ GET ดังนี้ -
@GET
@Path("/movie/{id}/")
ฐานข้อมูลภาพยนตร์นั้นเริ่มต้นด้วยเมธอด init ซึ่งเราจะเพิ่มรายการภาพยนตร์ห้ารายการลงในฐานข้อมูล
งานต่อไปของเราคือการเขียนโปรแกรมเซิร์ฟเวอร์
กำลังพัฒนาเซิร์ฟเวอร์
ในการสร้างเซิร์ฟเวอร์เราใช้ CXF ที่ให้มา JAXRSServerFactoryBean ชั้นเรียน
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
เราตั้งค่าคลาสทรัพยากรโดยเรียกไฟล์ setResourceClasses วิธี.
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
เราตั้งค่าผู้ให้บริการโดยโทรไปที่ไฟล์ setResourceProvider วิธี.
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
เราตั้งค่าที่ต้องการ publish ที่อยู่โดยโทร aetAddress วิธีการ -
factory.setAddress("http://localhost:9000/");
สุดท้ายเราเผยแพร่เซิร์ฟเวอร์โดยเรียกใช้เมธอด create บนไฟล์ factory ตัวอย่าง.
factory.create();
รหัสทั้งหมดสำหรับแอปพลิเคชันเซิร์ฟเวอร์ได้รับด้านล่าง -
//Server.java
package com.tutorialspoint.cxf.jaxrs.movie;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
public class Server {
public static void main(String[] args) throws Exception {
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
factory.setAddress("http://localhost:9000/");
factory.create();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
pom.xml สุดท้าย
เราได้รวมเวอร์ชันสุดท้ายของ 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.tutorialspoint</groupId>
<artifactId>cxf-jaxrs</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<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>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxrs.movie.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxrs.movie.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
</dependencies>
</project>
การพัฒนาลูกค้า
การเขียนไคลเอ็นต์ RS เป็นเรื่องเล็กน้อย เราเพียงแค่สร้างออบเจ็กต์ URL และเปิดสตรีม เราใช้คลาส IOUtils ที่ให้มาของ CXF เพื่อคัดลอกเนื้อหาของอินพุตสตรีมไปยังสตรีมในเครื่อง
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
}
รหัสทั้งหมดสำหรับแอปพลิเคชันไคลเอนต์มีให้ด้านล่าง -
//Client.java
package com.tutorialspoint.cxf.jaxrs.movie;
import java.io.InputStream;
import java.net.URL;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
String str = outstream.getOut().toString();
System.out.println(str);
}
}
}
การทดสอบแอปพลิเคชัน JAX-RS
เรียกใช้เซิร์ฟเวอร์โดยใช้คำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่ง -
mvn -Pserver
ตอนนี้คุณจะเห็นข้อความต่อไปนี้บนคอนโซล -
INFO: Setting the server's publish address to be http://localhost:9000
ตอนนี้เปิดเบราว์เซอร์ของคุณและพิมพ์ URL ต่อไปนี้ -
http://localhost:9000/movieservice/movie/1002
คุณจะเห็นสิ่งต่อไปนี้ในหน้าต่างเบราว์เซอร์
คุณสามารถเรียกใช้บริการโดยใช้แอ็พพลิเคชันไคลเอนต์ Java ที่เราได้พัฒนาขึ้นโดยรันคำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่งแยกต่างหาก
mvn -Pclient
คุณจะเห็นผลลัพธ์ต่อไปนี้ -
<?xml version="1.0" encoding = "UTF-8" standalone="yes"?>
<Movie><id>1002</id><name>Mission Imposssible</name></Movie>
ตัวอย่าง CXF มีหลายตัวอย่างเกี่ยวกับวิธีใช้ CXF กับ JAX-RS ผู้อ่านที่สนใจควรศึกษาตัวอย่างเหล่านี้