[JAVA] Beispiel für eine minimale RESTful-API-Konfiguration mit Jersey + Spring Framework

Dies ist eine Fortsetzung dieses Artikels.

Konfiguration mit mehreren Modulen mit Maven (Jersey RESTful) https://qiita.com/kasa_le/items/db0d84e3e868ff14bc2b

Zweck

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.

Tor

Hello World-like funktioniert mit dem Mindestkonfigurationsprogramm von Jersey + Spring Framework.

Umwelt etc.

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

Referenzseite

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.

Verfahren zur Projekteinstellung

1. Erstellen Sie ein neues Maven-Projekt

Erstellen Sie ein neues Maven-Projekt in IntelliJ IDEA. Informationen zum Verfahren finden Sie unter hier.

2. Legen Sie Abhängigkeiten fest

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>

3. Erstellen Sie eine Transaktionsklasse

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";
    }
}

4. Erstellen Sie eine Serviceklasse

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>
  1. web.xml

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 eine Jersey-Klasse ist. Ändern Sie außerdem den Paketnamen in den von Ihnen erstellten.

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>

Lauf

Wenn Sie die Ausführungseinstellungen in Tomcat festlegen und starten, sollte der folgende Bildschirm angezeigt werden.

jersey_spring_1.png

Wenn Sie auf den Link "Jersey Resource" klicken, wird die "GET" -Methode "Rest / Payment / Mkyong" aufgerufen und der Rückgabewert angezeigt.

jersery_spring_2.png

Curl und Postman sollten ebenfalls erfolgreich sein.

Prüfung

Ich werde einen Test schreiben, weil es eine große Sache ist.

1. Einfacher Test

(1) Abhängigkeit hinzufügen

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>

(2) Durchführung der Testklasse

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");
    }
}

2. Versuchen Sie, die Implementierung von TransactionBo zu ändern

Da es eine große Sache ist, habe ich versucht, mit Spring DI zu prüfen, ob es durch ein Modell ersetzt werden kann.

(1) Abhängigkeit hinzufügen

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>

(2) Erstellen Sie eine Mock-Bean-Klasse

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".

(3) Änderung der Testklasse

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.

Impressionen

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, in 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

Andere Referenzseiten

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

Beispiel für eine minimale RESTful-API-Konfiguration mit Jersey + Spring Framework
RESTful API-Beispiel für mehrere Module mit IntelliJ + Jersey + Spring Framework
Spring Boot: Restful API-Beispielprojekt
Fügen Sie die Datei in die Eigenschaften eines Strings mit Spring XML-Konfiguration ein
So legen Sie ein Profil mit annotationsbasierter Konfiguration im Spring-Framework fest und verwenden es
Spring Framework 5.0 Zusammenfassung der wichtigsten Änderungen
Spring Boot Access Authorization RESTful API
Implementieren Sie die REST-API mit Spring Boot
Einstellungen beim Aufrufen der API mithilfe von CSRF-Maßnahmen von Spring Security in JMeter
Informationen zur ersten Anzeige von Spring Framework
Wichtige Änderungen in der Kernfunktionalität von Spring Framework 5.0
Funktionen des Spring Frameworks für Java-Entwickler
Maven-Konfigurationsproblem mit Spring pom.xml in Eclipse
Beispielcode zum Aufrufen der Yahoo! Shopping Product Search (v3) -API mit Spring RestTemplate