带有 XML 参数的 REST 服务操作上的 HTTP 错误 415 不受支持的媒体类型(Jersey + Jetty)
Posted
技术标签:
【中文标题】带有 XML 参数的 REST 服务操作上的 HTTP 错误 415 不受支持的媒体类型(Jersey + Jetty)【英文标题】:HTTP Error 415 Unsupported Media Type on REST service operation with an XML parameter (Jersey + Jetty ) 【发布时间】:2019-10-08 22:50:16 【问题描述】:我使用 Jersey 和 Jetty 开发了一个 REST 服务。该服务有两个操作:
获取资源测试 在使用以 XML 形式发送的 Employee 实例的资源员工上发布 POST当我调用测试操作时,一切都按预期工作,并且我在服务输出中看到了打印的消息。但是,当我尝试调用 POST 操作时,我收到 HTTP 错误 415。
编译项目并生成我正在使用maven的jar文件,这是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>
而这些是服务使用的两个类的代码:Service(服务实现)
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 对象的转换。
【问题讨论】:
能否在进行休息调用时提供 Content-type 作为 application/xml 并在 getEmployee 方法中添加 @Produces(MediaType.APPLICATION_XML) 我得到了同样的结果。我编辑问题以在 curl 命令上添加标题 在 getEmployee 方法中添加 @Produces(MediaType.APPLICATION_XML)。添加后检查是否工作正常。 糟糕!我在以前的版本上尝试过,我认为它已经存在了。刚加回来,问题依旧 Add the service file transformer 到你的 maven shade 插件配置 【参考方案1】:我试过你的代码。绝对没问题。我在 Post REST Client 中尝试过,它工作正常。 curl 命令有问题。找到下面的 curl 命令进行测试。
curl -XPOST http://localhost:46100/api/employee -H "Content-type: application/xml" -d "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Employee><employeeName>Jack</employeeName></Employee>"
我做了以下修改。
删除了 -v 选项 在网址中添加了 http://如果是 RESTful webservice,您可以使用以下工具进行测试,这些工具非常有用。
Postman REST 客户端 (https://www.getpostman.com/downloads/) Insomnia REST 客户端 (https://insomnia.rest/)【讨论】:
检查并告诉我,我在 windows 机器上使用 curl 命令进行测试。 查看此链接,您将了解。 github.com/debjava/jetty-jersey-rest 如果你使用eclipse,可以将项目导入为maven项目。 我正在尝试从 github 链接运行项目,但遇到了同样的问题 有什么问题?【参考方案2】:maven-shade 插件配置错误。替换为
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>$maven-shade-plugin.version</version>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
解决问题
【讨论】:
以上是关于带有 XML 参数的 REST 服务操作上的 HTTP 错误 415 不受支持的媒体类型(Jersey + Jetty)的主要内容,如果未能解决你的问题,请参考以下文章
如果流被释放,带有 Stream 参数的 WCF REST 服务会抛出 400
使用 alamofire 将带有 JSON 对象和查询参数的 POST 请求发送到 REST Web 服务