Ceci est une suite de cet article.
Configuration multi-modules avec Maven (Jersey RESTful) https://qiita.com/kasa_le/items/db0d84e3e868ff14bc2b
Implémentez l'API RESTful avec ** Jersey ** et ** Spring Framework ** (pas Boot).
Si vous regardez Java Spring
, il n'y a que des exemples de ** Spring Boot **, et il est peut-être plus facile d'utiliser Boot, mais il peut ne pas être utilisable en raison de circonstances adultes, donc ** Spring Framework ** est recommandé. Visez l'échantillon utilisé.
Hello World-like fonctionne avec le programme de configuration minimum de Jersey + Spring Framework.
Outils 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 |
Ajouté à mon propre projet Jersey et projet Spring MVC Hello World J'ai essayé, mais quand j'ai cherché des informations, beaucoup d'entre eux utilisaient Spring Boot, donc c'était assez difficile.
J'ai enfin trouvé ce site.
Jersey + Spring integration example https://mkyong.com/webservices/jax-rs/jersey-spring-integration-example/
Ce sont des informations il y a environ 10 ans, et elles sont assez anciennes, mais le projet en cours vient de fonctionner. (* Cependant, dans l'environnement JDK9 ou version ultérieure, il est nécessaire d'ajouter des dépendances liées à JAXB) Donc, j'ai eu l'intention de passer de là à la dernière version et j'ai réussi, donc je vais prendre note du formulaire final.
Créez un nouveau projet Maven dans IntelliJ IDEA. Veuillez consulter ici pour la procédure.
Le pom.xml
ressemble à ceci:
Ce qui est différent du site de référence, c'est que chaque version est la dernière version et que le package a été déplacé en conséquence. De plus, étant donné que JAXB a été supprimé depuis JDK9, sa dépendance est également ajoutée.
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 supprimé de JDK9-->
<!-- 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>
C'est une classe à injecter par Bean. Cela semble être une méthode pour créer une interface et l'implémenter, mais il n'y a aucun problème même si ce n'est pas le cas. L'un des arguments de vente de Spring est ** DI ** (injection de dépendances), donc si vous pensez à vous moquer lors des tests ultérieurs, vous devriez le faire depuis le début.
Classe d'interface
transaction/TransactionBo.java
public interface TransactionBo {
String save();
}
Classe d'implémentation
transaction/impl/TransactionBoImpl.java
public class TransactionBoImpl implements TransactionBo {
public String save() {
return "Jersey + Spring example";
}
}
Demandez à Spring DI le TransactionBoImpl
, mais n'utilisez pas l'annotation @ Autowired
.
Utilisez l'injection de constructeur.
(L'injection du constructeur semble recommandée. Pour plus de détails, voir le site de référence à la fin)
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
Il s'agit d'un fichier pour définir la classe de bean à injecter.
Placez-le sous le dossier src / main / resources
.
Remplacez le nom du package et la classe du bean par ceux que vous avez créés.
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>
Créez web.xml
sous` src / main / webapp / WEB-INF / ʻet procédez comme suit.
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>
La seule différence avec le site de référence est que «
6.index.jsp
Placez-le sous le dossier webapp
.
Vous n'êtes pas obligé, mais si vous ne le faites pas, lorsque vous déployez sur Tomcat et que vous le démarrez, la page 404 sera affichée et ce sera désagréable (^^;
index.jsp
<html>
<body>
<h2>Jersey + Spring RESTful Web Application!</h2>
<p><a href="rest/payment/mkyong">Jersey resource</a>
</body>
</html>
Si vous définissez les paramètres d'exécution dans Tomcat et que vous le démarrez, vous devriez voir l'écran suivant.
Cliquez sur le lien «Jersey Resource» pour accéder à la méthode «GET» de «rest / payment / mkyong» et afficher la valeur de retour.
curl et Postman devraient également réussir.
J'écrirai un test car c'est un gros problème.
Ajoutez une dépendance pour les tests. Je l'ai fait de la même manière que lorsque cet article.
Tout d'abord, ajoutez des plugins sous <build> / <plugins>
.
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>
Ensuite, ajoutez-le à `
pom.xml
<!--tester-->
<!-- 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>
En gros, suivez simplement ce que vous avez fait dans 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");
}
}
Comme c'est un gros problème, j'ai essayé d'utiliser Spring DI pour voir s'il pouvait être remplacé par un simulacre.
Afin d'exécuter la DI de Spring, nous inclurons le framework de test de Spring.
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
Créez la classe suivante sous src / test / java / my / example / transaction / impl
.
TransactionBoMock.java
public class TransactionBoMock implements TransactionBo {
public String save() {
return "This is mock.";
}
}
Nous définirons cela comme un bean, mais comme il s'agit d'un test, nous créerons ʻapplicationContext.xmlpour le test. Placez-le sous
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>
Je change la classe d'implémentation en TransactionBoMock
.
Le style d'écriture correspond à «Junit5».
PaymentServiceTest.java
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:/applicationContext.xml")
class PaymentServiceTest extends JerseyTest {
Ajoutez simplement deux annotations! Si vous le faites, vous obtiendrez une erreur car vous n'avez pas encore modifié la chaîne de comparaison.
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");
Changez la chaîne ci-dessus en "" Ceci est simulé ". Et vous avez terminé.
Il faut beaucoup de temps pour arriver ici, mais ...
Quand c'est fait, c'est relativement simple.
Si cela devient si simple, il sera plus facile de comprendre qu'il est nécessaire de définir
En ce qui concerne l'installation de Spring MVC, la configuration du contrôleur et du répartiteur semble à nouveau être difficile, mais comme cela n'est prévu que pour l'API RESTful, cela convient une fois. (Je n'ai pas tellement envie d'étudier Spring MVC)
Ensuite, je voudrais créer une API plus décente et, si possible, la fusionner avec Projet multi-modulaire avec Jersey uniquement.
Les projets à ce jour sont téléchargés ci-dessous.
https://github.com/le-kamba/spring-jersey-sample/tree/simple_base
Les informations étaient obsolètes et pour Boot, donc ce n'était pas une référence directe, mais c'est un site qui m'a donné divers indices en détail.
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/
Pourquoi l'injection de constructeur est recommandée par rapport à l'injection de champ au printemps http://pppurple.hatenablog.com/entry/2016/12/29/233141
Comment faire fonctionner DI lors du test avec JUnit https://wikiwiki.jp/webapp/Spring/JUnit
JUnit5 @RunWith https://www.baeldung.com/junit-5-runwith
Recommended Posts