Dies ist eine Fortsetzung des folgenden Artikels.
Beispiel für eine minimale RESTful-API-Konfiguration mit Jersey + Spring Framework https://qiita.com/kasa_le/items/59ebd6b5490945dd5580
Konfiguration mit mehreren Modulen mit Maven (Jersey RESTful) https://qiita.com/kasa_le/items/db0d84e3e868ff14bc2b
Diesmal ist es so, als würden Sie die in den beiden oben genannten Artikeln erstellten Projekte zusammenführen. Ich werde es jedoch erklären, indem ich ein Projekt von Grund auf neu erstelle.
Implementieren Sie die RESTful-API mit ** Jersey ** und ** Spring Framework ** (nicht Boot).
--Jersey + Spring Framework funktioniert mit RESTful API (CRUD). --DI kann mit einer Konfiguration mit mehreren Modulen durchgeführt werden.
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 |
Erstellen Sie in IntelliJ ein neues "Maven-Projekt".
Grundsätzlich können Sie die Abhängigkeits- und Plug-In-Einstellungen aus dem Projekt Jersey + Spring Framework-Mindestkonfiguration kopieren.
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>jersey-spring-restful</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Jersey and Spring Framework RESTfulAPI Sample</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<inherited>true</inherited>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<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>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Jersey -->
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-server -->
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</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>
<!--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>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<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>
Löschen Sie es manuell.
Fügen Sie im IntelliJ-Menü [Datei] - [Neu] - [Modul ...] die folgenden beiden im Maven-Projekt hinzu.
Der Name des Submoduls ist beliebig. Vergessen Sie nicht, ** Parent ** einzustellen. (Bitte wählen Sie das Root-Projekt aus.)
Dann sollte sich das
root/pom.xml
<groupId>my.example.jerseyspring</groupId>
<artifactId>jersey-spring-restful</artifactId>
<packaging>pom</packaging>
Jede pom.xml
des Submoduls sollte folgendermaßen aussehen:
repository/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">
<parent>
<artifactId>jersey-spring-restful</artifactId>
<groupId>my.example.jerseyspring</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>repository</artifactId>
<packaging>jar</packaging>
</project>
serverapi/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">
<parent>
<artifactId>jersey-spring-restful</artifactId>
<groupId>my.example.jerseyspring</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>serverapi</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>my.example.jerseyspring</groupId>
<artifactId>repository</artifactId>
<version>${project.version}</version>
</dependency>
<!-- for spring test-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Das Serverapi-Modul ist im Bereich "
Weder hat ihre eigene Version angegeben. Ich möchte die übergeordnete Version so verwenden, wie sie ist.
Es ist eine Richtlinie, die Version nicht für jedes Submodul zu verwalten. Geben Sie bei Bedarf die jeweilige Version mit dem Tag "
Die aktuelle Ordnerstruktur sollte so aussehen.
$ tree
.
├── SpringJerseyRest.iml
├── pom.xml
├── repository
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── java
│ │ └── resources
│ └── test
│ └── java
└── serverapi
├── pom.xml
└── src
├── main
│ ├── java
│ └── resources
└── test
└── java
Erstellen Sie die folgenden Klassen im Paket "my.example.jerseyspring.repository.models".
Employee.java
package my.example.jerseyspring.repository.models;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Employee {
private int id;
private String firstName;
public Employee() {
}
public Employee(int id, String firstName) {
this.id = id;
this.firstName = firstName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
Erstellen Sie eine "EmployeeRepository" -Klasse im Paket "my.example.jerseyspring.repository".
EmployeeRepository.java
package my.example.jerseyspring.repository;
import my.example.jerseyspring.repository.exceptions.DuplicateIdException;
import my.example.jerseyspring.repository.exceptions.EmployeeNameNotFoundException;
import my.example.jerseyspring.repository.exceptions.EmployeeNotFoundException;
import my.example.jerseyspring.repository.models.Employee;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class EmployeeRepository {
private List<Employee> employeeList;
public EmployeeRepository() {
employeeList = new ArrayList<>();
employeeList.add(new Employee(3, "Cupcake"));
employeeList.add(new Employee(4, "Donuts"));
employeeList.add(new Employee(5, "Eclair"));
employeeList.add(new Employee(8, "Froyo"));
employeeList.add(new Employee(9, "Gingerbread"));
}
public List<Employee> selectAll() {
return employeeList;
}
public Employee select(int id) {
for (Employee employee : employeeList) {
if (employee.getId() == id) {
return employee;
}
}
throw new EmployeeNotFoundException();
}
public synchronized void insert(int id, String firstName) {
try {
select(id);
} catch (EmployeeNotFoundException e) {
//Wenn nicht, können Sie hinzufügen
employeeList.add(new Employee(id, firstName));
return;
}
//Kann nicht hinzugefügt werden, wenn dieselbe ID vorhanden ist
throw new DuplicateIdException();
}
public synchronized void update(int id, String firstName) {
Employee employee = select(id);
employee.setFirstName(firstName);
}
public synchronized void delete(int id) {
Employee employee = select(id);
employeeList.remove(employee);
}
public List<Employee> search(String name) {
List<Employee> list = new ArrayList<>();
for (Employee employee : employeeList) {
if (employee.getFirstName().contains(name)) {
list.add(employee);
}
}
if (list.size() > 0) return list;
throw new EmployeeNameNotFoundException(name);
}
}
Im vorherigen Multi-Modul-Beispiel war die Singleton-Implementierung selbst enthalten, aber der DI des Spring Framework ist im Grunde genommen Singleton. , Entfernen seiner Implementierung.
Erstellen Sie jede Ausnahmeklasse, die in der Klasse "EmployeeRepository" verwendet wird. Das Paket ist "repository.exceptions".
Beispiel) Klasse "EmployeeNotFoundException"
EmployeeNotFoundException.java
package my.example.jerseyspring.repository.exceptions;
public class EmployeeNotFoundException extends RuntimeException {
public EmployeeNotFoundException() {
super("Der Mitarbeiter mit dieser ID kann nicht gefunden werden.");
}
}
Erstellen Sie andere Klassen auf die gleiche Weise.
Außerdem werde ich das "Transacation" -Paket mitbringen, das im Projekt Jersey + Spring Minimum Configuration verwendet wird. Das Paket "repository.transaction" ist in Ordnung.
Erstellen Sie eine Testklasse für die Ausnahmeklasse.
Nehmen wir als Beispiel den Fall "EmployeeNotFoundException".
EmployeeNotFoundExceptionTest.java
package my.example.jerseyspring.repository.exceptions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class EmployeeNotFoundExceptionTest {
@Test
void getMessage() {
EmployeeNotFoundException e = new EmployeeNotFoundException();
assertThat(e.getMessage()).isEqualTo("Der Mitarbeiter mit dieser ID kann nicht gefunden werden.");
}
}
Führen Sie in IntelliJ den Junit-Test aus und überprüfen Sie, ob er erfolgreich ist.
Am Ende sollten Sie eine Ordnerstruktur wie diese haben:
$ tree
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── my
│ │ └── example
│ │ └── jerseyspring
│ │ └── repository
│ │ ├── EmployeeRepository.java
│ │ ├── exceptions
│ │ │ ├── DuplicateIdException.java
│ │ │ ├── EmployeeNameNotFoundException.java
│ │ │ └── EmployeeNotFoundException.java
│ │ ├── models
│ │ │ └── Employee.java
│ │ └── transaction
│ │ ├── TransactionBo.java
│ │ └── impl
│ │ └── TransactionBoImpl.java
│ └── resources
└── test
└── java
└── my
└── example
└── jerseyspring
└── repository
└── exceptions
├── DuplicateIdExceptionTest.java
├── EmployeeNameNotFoundExceptionTest.java
└── EmployeeNotFoundExceptionTest.java
19 directories, 11 files
Erstellen Sie eine "EmployeeService" -Klasse im Paket "my.example.jerseyspring.rest".
EmployeeService.java
package my.example.jerseyspring.rest;
import my.example.jerseyspring.repository.EmployeeRepository;
import my.example.jerseyspring.repository.models.Employee;
import org.springframework.stereotype.Service;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.util.List;
@Service
@Path("/employees")
public class EmployeeService {
final EmployeeRepository employeeRepository;
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
@Context
UriInfo uriInfo;
@GET
@Path("/all")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Employee> getAll() {
return employeeRepository.selectAll();
}
@GET
@Path("/{id}")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Employee getEmployee(@PathParam("id") int id) {
return employeeRepository.select(id);
}
@GET
@Path("/search")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public List<Employee> searchEmployee(@QueryParam("name") String name) {
return employeeRepository.search(name);
}
@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response addEmployee(Employee employee) {
employeeRepository.insert(employee.getId(), employee.getFirstName());
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(String.valueOf(employee.getId()));
return Response.created(builder.build()).build();
}
@PUT
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response updateEmployee(Employee employee) {
employeeRepository.update(employee.getId(), employee.getFirstName());
//Wenn Sie ein neues erstellen, müssen Sie erstellt zurückgeben. In diesem Beispiel handelt es sich jedoch um einen Fehler, sodass immer OK zurückgegeben wird.
return Response.ok().build();
}
@DELETE
@Path("/{id}")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Response deleteEmployee(@PathParam("id") int id) {
employeeRepository.delete(id);
//Um den Status der Entität zurückzugeben, geben Sie ok zurück.
//Wenn es akzeptiert wird, der Vorgang jedoch nicht abgeschlossen ist(Ich bin gerade auf das Stichwort gekommen usw.)Rückgabe akzeptiert
//In diesem Beispiel ist nur das Löschen abgeschlossen und der entsprechende Inhalt ist erschöpft.
return Response.noContent().build();
}
}
Außerdem werde ich die im Projekt Jersey + Spring-Mindestkonfiguration verwendete Klasse "PaymentService" mitbringen.
Erstellen Sie eine Klasse für die Ausnahmezuordnung im Paket "rest.handlers". Erforderlich für jede vom Repository-Modul erstellte Ausnahmeklasse. Klicken Sie hier, um eine Ausnahmezuordnung zu erhalten (https://qiita.com/kasa_le/items/3c7e7a426acf846ee64e#%E4%BE%8B%E5%A4%96%E3%83%8F%E3%83%B3%E3) Bitte beziehen Sie sich auf% 83% 89% E3% 83% AA% E3% 83% B3% E3% 82% B0).
Beispiel) Mapper der Klasse "EmployeeNotFoundException"
NotFoundExceptionHandler.java
package my.example.jerseyspring.rest.handler;
import my.example.jerseyspring.repository.exceptions.EmployeeNotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class NotFoundExceptionHandler implements ExceptionMapper<EmployeeNotFoundException> {
public Response toResponse(EmployeeNotFoundException ex) {
return Response.status(Response.Status.NOT_FOUND).build();
}
}
Erstellen Sie applicationContext.xml
unter src / main / resources
und machen Sie es wie folgt.
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.repository.transaction.impl.TransactionBoImpl"/>
<bean id="employeeRepository" class="my.example.jerseyspring.repository.EmployeeRepository"/>
</beans>
Erstellen Sie einen Ordner "src / main / webapp".
--Erstelle web.xml
unter webapp / WEB-INF
und mache daraus den folgenden Inhalt
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<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-servlet</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-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
--Erstelle index.jsp
unter webapp /
und mache es wie folgt
index.jsp
<html>
<body>
<h2>Jersey + Spring RESTful Web Application!</h2>
<p><a href="rest/payment/mkyong">Jersey resource</a>
<br>
<p><a href="rest/employees/all">All Employee List</a>
<p><a href="rest/employees/3">get id=3 employee</a>
</body>
</html>
Erstellen Sie eine "EmployeeServiceTest" -Klasse und eine "PaymentServiceTest" -Klasse und schreiben Sie einen Test.
EmployeeServiceTest.java
package my.example.jerseyspring.rest;
import my.example.jerseyspring.repository.EmployeeRepository;
import my.example.jerseyspring.repository.models.Employee;
import my.example.jerseyspring.rest.handler.DuplicateExceptionHandler;
import my.example.jerseyspring.rest.handler.NameNotFoundExceptionHandler;
import my.example.jerseyspring.rest.handler.NotFoundExceptionHandler;
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 org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.stream.Stream;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:/applicationContext.xml")
public class EmployeeServiceTest extends JerseyTest {
@Autowired
EmployeeRepository employeeRepository;
@Override
protected Application configure() {
return new ResourceConfig(EmployeeService.class)
.register(DuplicateExceptionHandler.class)
.register(NameNotFoundExceptionHandler.class)
.register(NotFoundExceptionHandler.class)
.register(this);
}
@BeforeEach
@Override
public void setUp() throws Exception {
super.setUp();
}
@AfterEach
@Override
public void tearDown() throws Exception {
super.tearDown();
}
@ParameterizedTest
@ValueSource(strings = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public void getAll(String mediaType) {
final Response response = target("/employees/all").request().accept(mediaType).get();
assertThat(response.getHeaderString("Content-Type"))
.isEqualTo(mediaType);
List<Employee> content = response.readEntity(new GenericType<>() {
});
assertThat(content.size()).isEqualTo(5);
assertThat(content.get(0)).isEqualToComparingFieldByField(new Employee(3, "Cupcake"));
assertThat(content.get(1)).isEqualToComparingFieldByField(new Employee(4, "Donuts"));
assertThat(content.get(2)).isEqualToComparingFieldByField(new Employee(5, "Eclair"));
assertThat(content.get(3)).isEqualToComparingFieldByField(new Employee(8, "Froyo"));
assertThat(content.get(4)).isEqualToComparingFieldByField(new Employee(9, "Gingerbread"));
}
@ParameterizedTest
@MethodSource("getParamProvider")
public void getEmployee(int id, String mediaType) {
String urlPath = String.format("/employees/%d", id);
final Response response = target(urlPath).request().accept(mediaType).get();
assertThat(response.getHeaderString("Content-Type"))
.isEqualTo(mediaType);
Employee employee = response.readEntity(Employee.class);
Employee expect = employeeRepository.select(id);
assertThat(employee).isEqualToComparingFieldByField(expect);
}
static Stream<Arguments> getParamProvider() {
return Stream.of(
Arguments.of(3, MediaType.APPLICATION_JSON),
Arguments.of(4, MediaType.APPLICATION_JSON),
Arguments.of(5, MediaType.APPLICATION_JSON),
Arguments.of(8, MediaType.APPLICATION_JSON),
Arguments.of(9, MediaType.APPLICATION_JSON),
Arguments.of(3, MediaType.APPLICATION_XML),
Arguments.of(4, MediaType.APPLICATION_XML),
Arguments.of(5, MediaType.APPLICATION_XML),
Arguments.of(8, MediaType.APPLICATION_XML),
Arguments.of(9, MediaType.APPLICATION_XML)
);
}
@ParameterizedTest
@ValueSource(strings = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public void searchEmployee(String mediaType) {
final Response response = target("/employees/search")
.queryParam("name", "a")
.request()
.accept(mediaType)
.get();
assertThat(response.getHeaderString("Content-Type"))
.isEqualTo(mediaType);
List<Employee> content = response.readEntity(new GenericType<>() {
});
assertThat(content.size()).isEqualTo(3);
assertThat(content.get(0)).isEqualToComparingFieldByField(new Employee(3, "Cupcake"));
assertThat(content.get(1)).isEqualToComparingFieldByField(new Employee(5, "Eclair"));
assertThat(content.get(2)).isEqualToComparingFieldByField(new Employee(9, "Gingerbread"));
}
@ParameterizedTest
@MethodSource("postRawProvider")
public void addEmployee(int id, String bodyRaw, String mediaType) {
final Response response = target("/employees").request()
.post(Entity.entity(bodyRaw, mediaType));
assertThat(response.getStatus()).isEqualTo(201);
assertThat(response.getHeaderString("Location"))
.isEqualTo("http://localhost:9998/employees/" + id);
}
static Stream<Arguments> postRawProvider() {
final String json = "{\"firstName\":\"Honeycomb\",\"id\":11}";
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<employee><firstName>KitKat</firstName><id>19</id></employee>";
return Stream.of(
Arguments.of(11, json, MediaType.APPLICATION_JSON),
Arguments.of(19, xml, MediaType.APPLICATION_XML)
);
}
@ParameterizedTest
@MethodSource("putRawProvider")
public void updateEmployee(int id, String bodyRaw, String mediaType) {
final Response response = target("/employees").request()
.put(Entity.entity(bodyRaw, mediaType));
assertThat(response.getStatus()).isEqualTo(200);
Employee employee = target("/employees/" + id).request().get(Employee.class);
Employee expected = employeeRepository.select(id);
assertThat(employee).isEqualToComparingFieldByField(expected);
}
static Stream<Arguments> putRawProvider() {
final String json = "{\"firstName\":\"Frozen yogurt\",\"id\":8}";
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<employee><firstName>Cup Cake</firstName><id>3</id></employee>";
return Stream.of(
Arguments.of(8, json, MediaType.APPLICATION_JSON),
Arguments.of(3, xml, MediaType.APPLICATION_XML)
);
}
@Test
public void deleteEmployee() {
final Response response = target("/employees/9")
.request().delete();
assertThat(response.getStatus()).isEqualTo(204);
}
@Test
public void exception_selectEmployee() {
final Response response = target("/employees/1").request().get();
assertThat(response.getStatus()).isEqualTo(404);
}
@Test
public void exception_searchEmployee() {
final Response response = target("/employees/search?name=android").request().get();
assertThat(response.getStatus()).isEqualTo(404);
}
@ParameterizedTest
@MethodSource("putRawProvider")
public void exception_addEmployee(int id, String bodyRaw, String mediaType) {
final Response response = target("/employees").request()
.post(Entity.entity(bodyRaw, mediaType));
assertThat(response.getStatus()).isEqualTo(409);
}
@ParameterizedTest
@MethodSource("putExceptionProvider")
public void exception_updateEmployee(int id, String bodyRaw, String mediaType) {
final Response response = target("/employees").request()
.put(Entity.entity(bodyRaw, mediaType));
assertThat(response.getStatus()).isEqualTo(404);
}
static Stream<Arguments> putExceptionProvider() {
final String json = "{\"firstName\":\"Lollipop\",\"id\":21}";
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<employee><firstName>Jelly Bean</firstName><id>17</id></employee>";
return Stream.of(
Arguments.of(21, json, MediaType.APPLICATION_JSON),
Arguments.of(3, xml, MediaType.APPLICATION_XML)
);
}
@Test
public void exception_deleteEmployee() {
final Response response = target("/employees/1").request().get();
assertThat(response.getStatus()).isEqualTo(404);
}
}
In Beispiel mit mehreren Modulen ist der Teil, der das Sington-Objekt als "EmployeeRepository.getInstance" erworben hat, die von "@ Autowired" deklarierte Mitgliedsvariable. Zugriff und Änderung. Mit der Annotation "@ Autowired" wird Spring für Sie DI, aber tatsächlich scheinen verschiedene Instanzen für die Person, die tatsächlich mit dem Dienst arbeitet, und die Person, die testet, erstellt zu werden (es sollte ein Singleton sein, aber wahrscheinlich der Test). Ich habe einen Artikel gesehen, der besagt, dass es in Ordnung ist, "ResourceConfig # register (this)" auszuführen (da sich der Kontext vom Anwendungskontext unterscheidet). Ist es nicht ein Fehler, der damit funktioniert? Weil es eine Warnmeldung gibt? Es gibt auch eine Meinung, daher weiß ich nicht, ob es richtig ist. https://stackoverflow.com/questions/34453448/how-to-access-spring-bean-from-jerseytest-subclass
Dieses Mal ist die Repository-Klasse nicht das Hauptthema, sondern bietet nur temporären Datenzugriff, daher bin ich damit zufrieden. Beachten Sie jedoch, dass es möglicherweise nicht mehr funktioniert, wenn die Version von Spring oder Jersey steigt.
Die Klasse "PaymentServiceTest" wird auch aus dem Beispiel für die Mindestkonfiguration (https://qiita.com/kasa_le/items/59ebd6b5490945dd5580) übernommen. Bringen Sie außerdem die Klasse "TransactionBoMock" ein, die für den DI-Mock-Ersatztest erstellt wurde.
Fügen Sie dann eine applicationContext.xml
in den resources
-Ordner des test
-Ordners ein, damit Sie die Bean ersetzen können, und gehen Sie wie folgt vor:
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.repository.transaction.impl.TransactionBoMock"/>
<bean id="employeeRepository" class="my.example.jerseyspring.repository.EmployeeRepository"/>
</beans>
Da EmployeeRepository keine Schnittstelle hat, werde ich sie dieses Mal nicht ersetzen, aber ursprünglich sollte ich die Mocked-Klasse zum Testen der ursprünglichen Implementierung verwenden, die Daten aus der Datenbank usw. abruft.
Die Struktur des Ordners "serverapi" sollte folgendermaßen aussehen:
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── my
│ │ └── example
│ │ └── jerseyspring
│ │ └── rest
│ │ ├── EmployeeService.java
│ │ ├── PaymentService.java
│ │ └── handler
│ │ ├── DuplicateExceptionHandler.java
│ │ ├── NameNotFoundExceptionHandler.java
│ │ └── NotFoundExceptionHandler.java
│ ├── resources
│ │ └── applicationContext.xml
│ └── webapp
│ ├── WEB-INF
│ │ └── web.xml
│ └── index.jsp
└── test
├── java
│ └── my
│ └── example
│ └── jerseyspring
│ ├── repository
│ │ └── transaction
│ │ └── impl
│ │ └── TransactionBoMock.java
│ └── rest
│ ├── EmployeeServiceTest.java
│ └── PaymentServiceTest.java
└── resources
└── applicationContext.xml
21 directories, 13 files
(1)JUnitTest Führen Sie JUnitTest aus, um festzustellen, ob alle Tests bestanden wurden.
$ mvn clean test
Richten Sie Tomcat ein und stellen Sie es bereit.
Sie sollten eine Seite wie die folgende sehen, auf den Link klicken und den API-Rückgabewert sehen.
Wenn Sie die Ein- / Ausgabe des POST-Systems oder von Json / Xml überprüfen möchten, überprüfen Sie dies bitte mit Curl oder Postman.
Die bisherigen Projekte werden unten hochgeladen. https://github.com/le-kamba/spring-jersey-sample/tree/spring_jersey
Ich konnte es reibungslos machen, ohne süchtig zu werden, bis auf den Singleton-Teil.
Übrigens wurde die Ordnerstruktur gelöscht, indem der Befehl ** tree ** in Brew auf dem Mac eingefügt wurde. Ich musste es von der Installation von Homebrew an erster Stelle tun. (Hast du es nicht reingelegt?)
#Homebrew-Installation
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
#Installation des Baumes
$ brew install tree
Was ist der Unterschied zwischen Spring DI und New? https://qiita.com/uqichi/items/5f59817beb3dff9c0c1e
Recommended Posts