Dies ist eine Fortsetzung dieses Artikels.
Konfiguration mit mehreren Modulen mit Maven (Jersey RESTful) https://qiita.com/kasa_le/items/db0d84e3e868ff14bc2b
Implementieren Sie die RESTful-API mit ** Jersey ** und ** Spring Framework ** (nicht Boot).
Wenn Sie sich Java Spring
ansehen, gibt es nur Beispiele für ** Spring Boot **, und es ist wahrscheinlich einfacher, Boot zu verwenden, aber es ist möglicherweise aufgrund von Umständen für Erwachsene nicht möglich, es zu verwenden. Daher wird ** Spring Framework ** empfohlen. Ziel für die verwendete Probe.
Hello World-like funktioniert mit dem Mindestkonfigurationsprogramm von Jersey + Spring Framework.
Werkzeuge etc. | Version etc. |
---|---|
MacbookPro | macOS Mojave 10.14.5 |
IntelliJ IDEA | Ultimate 2019.3.3 |
Java | AdoptOpenJDK 11 |
apache maven | 3.6.3 |
Jersey | 2.30.1 |
JUnit | 5.6.0 |
Tomcat | apache-tomcat-8.5.51 |
Postman | 7.19.1 |
Spring Framework | 5.2.4-RELEASE |
Hinzugefügt zu meinem eigenen Jersey-Projekt und Spring MVC Hello World-Projekt Ich habe es versucht, aber als ich nach Informationen suchte, verwendeten viele von ihnen Spring Boot, so dass es ziemlich schwierig war.
Ich habe diese Seite endlich gefunden.
Jersey + Spring integration example https://mkyong.com/webservices/jax-rs/jersey-spring-integration-example/
Es sind Informationen vor ungefähr 10 Jahren und es ist ziemlich alt, aber das Projekt, das gerade läuft, hat gerade funktioniert. (* In der Umgebung von JDK9 oder höher müssen jedoch JAXB-bezogene Abhängigkeiten hinzugefügt werden.) Nachdem ich von dort aus auf die neueste Version upgraden wollte, war ich erfolgreich und werde mir das endgültige Formular notieren.
Erstellen Sie ein neues Maven-Projekt in IntelliJ IDEA. Informationen zum Verfahren finden Sie unter hier.
Die pom.xml
sieht folgendermaßen aus:
Was sich von der Referenzseite unterscheidet, ist, dass jede Version die neueste Version ist und das Paket entsprechend verschoben wurde. Da JAXB-bezogen seit JDK9 gelöscht wurde, wird auch seine Abhängigkeit hinzugefügt.
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>my.example.jerseyspring</groupId>
<artifactId>RESTfulExample</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>RESTfulExample Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- Jersey -->
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-server -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Jersey + Spring -->
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.ext/jersey-spring5 -->
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring5</artifactId>
<version>${jersey.version}</version>
</dependency>
<!--JAXB aus JDK9 entfernt-->
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.activation/activation -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
<build>
<finalName>RESTfulExample</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<inherited>true</inherited>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<spring.version>5.2.4.RELEASE</spring.version>
<jersey.version>2.30.1</jersey.version>
<junit.jupiter.version>5.6.0</junit.jupiter.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
Es ist eine Klasse, die von Bean injiziert wird. Es scheint eine Methode zu sein, eine Schnittstelle zu erstellen und zu implementieren, aber es gibt kein Problem, auch wenn dies nicht der Fall ist. Eines der Verkaufsargumente von Spring ist ** DI ** (Abhängigkeitsinjektion). Wenn Sie also beim späteren Testen über Spott nachdenken, sollten Sie dies von Anfang an tun.
Schnittstellenklasse
transaction/TransactionBo.java
public interface TransactionBo {
String save();
}
Implementierungsklasse
transaction/impl/TransactionBoImpl.java
public class TransactionBoImpl implements TransactionBo {
public String save() {
return "Jersey + Spring example";
}
}
Lassen Sie Spring DI das TransactionBoImpl
, aber verwenden Sie nicht die Annotation @ Autowired
.
Konstruktorinjektion verwenden.
(Konstruktorinjektion scheint empfohlen zu sein. Einzelheiten finden Sie auf der Referenzstelle am Ende.)
rest/PaymentService.java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import org.springframework.stereotype.Component;
import my.example.jerseyspring.transaction.TransactionBo;
@Component
@Path("/payment")
public class PaymentService {
final TransactionBo transactionBo;
public PaymentService(TransactionBo transactionBo) {
this.transactionBo = transactionBo;
}
@GET
@Path("/mkyong")
public Response savePayment() {
String result = transactionBo.save();
return Response.status(200).entity(result).build();
}
}
5.applicationContext.xml
Dies ist eine Datei zum Festlegen der zu injizierenden Bean-Klasse. Legen Sie es in den Ordner "src / main / resources". Ändern Sie den Paketnamen und die Bean-Klasse in die von Ihnen erstellten.
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="my.example.jerseyspring" />
<bean id="transactionBo" class="my.example.jerseyspring.transaction.impl.TransactionBoImpl" />
</beans>
Erstellen Sie "web.xml" unter "src / main / webapp / WEB-INF /" und gehen Sie wie folgt vor.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>Restful Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.example.jerseyspring</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Der einzige Unterschied zur Referenzseite besteht darin, dass
6.index.jsp
Legen Sie es unter den Ordner "webapp". Sie müssen nicht, aber wenn Sie dies nicht tun, wird beim Bereitstellen auf Tomcat und Starten eine 404-Seite angezeigt, die unangenehm ist (^^;
index.jsp
<html>
<body>
<h2>Jersey + Spring RESTful Web Application!</h2>
<p><a href="rest/payment/mkyong">Jersey resource</a>
</body>
</html>
Wenn Sie die Ausführungseinstellungen in Tomcat festlegen und starten, sollte der folgende Bildschirm angezeigt werden.
Wenn Sie auf den Link "Jersey Resource" klicken, wird die "GET" -Methode "Rest / Payment / Mkyong" aufgerufen und der Rückgabewert angezeigt.
Curl und Postman sollten ebenfalls erfolgreich sein.
Ich werde einen Test schreiben, weil es eine große Sache ist.
Fügen Sie eine Abhängigkeit zum Testen hinzu. Ich habe es genauso gemacht wie bei diesem Artikel.
Fügen Sie zunächst Plugins unter <build> / <plugins>
hinzu.
pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>src/test/java/</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>3.0.0-M4</version>
</plugin>
Fügen Sie es dann zu "<Abhängigkeiten>" hinzu.
pom.xml
<!--Prüfung-->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.test-framework.providers/jersey-test-framework-provider-grizzly2 -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.30.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.assertj/assertj-core -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.15.0</version>
<scope>test</scope>
</dependency>
Befolgen Sie einfach die Anweisungen in Jersey Basic Sample.
src/test/java/my/example/jerseysample/PaymentServiceTest.java
package my.example.jerseyspring.rest;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import static org.assertj.core.api.Assertions.assertThat;
class PaymentServiceTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(PaymentService.class);
}
@BeforeEach
@Override
public void setUp() throws Exception {
super.setUp();
}
@AfterEach
@Override
public void tearDown() throws Exception {
super.tearDown();
}
@Test
public void get(){
final Response response = target("/payment/mkyong").request().get();
String content = response.readEntity(String.class);
assertThat(content).isEqualTo("Jersey + Spring example");
}
}
Da es eine große Sache ist, habe ich versucht, mit Spring DI zu prüfen, ob es durch ein Modell ersetzt werden kann.
Um den DI von Spring auszuführen, werden wir das Test-Framework von Spring einschließen.
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
Erstellen Sie die folgende Klasse unter "src / test / java / my / example / transaction / impl".
TransactionBoMock.java
public class TransactionBoMock implements TransactionBo {
public String save() {
return "This is mock.";
}
}
Wir werden dies als Bean definieren, aber da es zum Testen dient, werden wir eine applicationContext.xml
zum Testen erstellen.
Platziere es unter "src / test / resources".
src/test/resources/applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="my.example.jerseyspring"/>
<bean id="transactionBo" class="my.example.jerseyspring.transaction.impl.TransactionBoMock"/>
</beans>
Ich ändere die Implementierungsklasse in "TransactionBoMock".
Der Schreibstil entspricht "Junit5".
PaymentServiceTest.java
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:/applicationContext.xml")
class PaymentServiceTest extends JerseyTest {
Fügen Sie einfach zwei Anmerkungen hinzu! In diesem Fall wird eine Fehlermeldung angezeigt, da Sie die Vergleichszeichenfolge noch nicht geändert haben.
org.opentest4j.AssertionFailedError:
Expecting:
<"This is mock.">
to be equal to:
<"Jersey + Spring example">
but was not.
Expected :Jersey + Spring example
Actual :This is mock.
assertThat(content).isEqualTo("Jersey + Spring example");
Ändern Sie die obige Zeichenfolge in "Dies ist ein Schein". Und Sie sind fertig.
Es dauert lange, bis wir hier sind, aber ...
Wenn es fertig ist, ist es relativ einfach.
Wenn es so einfach wird, ist es leichter zu verstehen, dass es notwendig ist, applicationContext.xml
zu definieren, um DI zu erhalten.
Wenn es um die Installation von Spring MVC geht, scheint es wieder schwierig zu sein, Controller und Dispatcher einzustellen. Da dies jedoch nur für die RESTful-API geplant ist, ist dies einmal in Ordnung. (Ich habe nicht so viel Lust, Spring MVC zu studieren)
Als nächstes möchte ich eine anständigere API erstellen und sie, wenn möglich, mit Projekt, das nur mit Jersey multimoduliert ist zusammenführen.
Die bisherigen Projekte werden unten hochgeladen.
https://github.com/le-kamba/spring-jersey-sample/tree/simple_base
Die Informationen waren veraltet und für Boot, daher war es kein direkter Verweis, aber es ist eine Seite, die mir verschiedene Hinweise im Detail gab.
REST API with Jersey and Spring https://www.baeldung.com/jersey-rest-api-with-spring
Programmers: Jersey with a Side of Spring http://pilotprogrammer.com/archive/2019/01/programmers-jersey-with-a-side-of-spring/
Warum die Konstruktorinjektion im Frühjahr gegenüber der Feldinjektion empfohlen wird http://pppurple.hatenablog.com/entry/2016/12/29/233141
So funktioniert DI beim Testen mit JUnit https://wikiwiki.jp/webapp/Spring/JUnit
JUnit5 @RunWith https://www.baeldung.com/junit-5-runwith
Recommended Posts