Я разработал REST-сервис с Джерси и Джетти. Служба имеет две операции:
- GET при тестировании ресурса
- POST для сотрудника ресурса, который использует экземпляр Employee, отправленный в виде XML
Когда я вызываю тестовую операцию, все работает как положено, и я вижу на выходе службы напечатанное сообщение. Однако, когда я пытаюсь вызвать операцию POST, я получаю ошибку HTTP 415.
Для компиляции проекта и создания jar-файла я использую maven, и это содержимое файла 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.test.app</groupId>
<artifactId>Service</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>
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
<maven-shade-plugin.version>2.4.3</maven-shade-plugin.version>
<maven-resources-plugin.version>3.0.1</maven-resources-plugin.version>
<maven-clean-plugin.version>3.0.0</maven-clean-plugin.version>
<maven-war-plugin.version>3.0.0</maven-war-plugin.version>
<tomcat7-maven-plugin.version>2.1</tomcat7-maven-plugin.version>
<maven-jaxb2-plugin.version>0.12.1</maven-jaxb2-plugin.version>
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
<jersey.version>2.26</jersey.version>
<jetty.version>9.4.3.v20170317</jetty.version>
</properties>
<!-- DEPENDENCIES -->
<dependencies>
<!-- REST Service-->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>${jetty.version}</version>
</dependency>
<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-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
</dependencies>
<!-- BUILD -->
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>packaging</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<silent>true</silent>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}</finalName>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
И это код двух классов, используемых сервисом: Сервис (реализация сервиса)
package com.test.app;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.servlet.ServletContainer;
@Path("/api")
public class Service {
@GET
@Path("test/")
public Response test() {
System.out.println("test invoked");
return Response.ok().build();
}
@POST
@Path("employee/")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public Response getEmployee(Employee employee) {
employee.setEmployeeName(employee.getEmployeeName() + " Welcome");
return Response.status(Status.OK).entity(employee).build();
}
public static void main(String[] args) throws Exception {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
int port = 46100;
Server jettyServer = new Server(port);
jettyServer.setHandler(context);
//org.eclipse.jetty.util.log.Log.getRootLogger().setDebugEnabled(true);
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", Service.class.getCanonicalName());
try {
jettyServer.start();
jettyServer.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
jettyServer.destroy();
}
}
}
и Employee (объект передан в качестве параметра функции)
package com.test.app;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Employee")
public class Employee {
String employeeName;
@XmlElement
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
}
Чтобы убедиться, что выполнение операции работает должным образом, я запускаю следующую команду curl:
curl -v -XPOST localhost:46100/api/employee -H "Content-type: application/xml" -d "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Employee>
<employeeName>Jack</employeeName>
</Employee>"
И ответ, который я получаю, - ошибка HTTP 415.
Я подозреваю, что мне не хватает некоторой зависимости от файла maven, необходимого только во время выполнения, которое содержит преобразование файла XML в фактический объект Employee.