【问题标题】:JAX-RS service always replies with 415 Unsupported Media Type error to POST requestsJAX-RS 服务始终以 415 Unsupported Media Type 错误回复 POST 请求
【发布时间】:2015-05-11 13:43:14
【问题描述】:

我知道(相当)类似的问题被问了很多次,但解决方案对我不起作用。

我正在使用 JAX-RS 和 Jersey 2 创建一个 REST 服务,它使用来自 post 请求的 json bean,它看起来像这样:

@Path("auth")
public class AuthService {
@Inject
private AuthenticationManager authenticationManager;

@POST
@Path("login")
@Consumes(MediaType.APPLICATION_JSON)
public Response login(ApiCredentials credentials){
    try {
        authenticationManager.login(credentials);
        return Response.ok().build();
    } catch (Exception e){
        e.printStackTrace();
        return Response.status(Response.Status.UNAUTHORIZED).build();
    }
}

并在以编程方式配置的嵌入式 tomcat 中运行

public class WebServer {
public static void main(String[] args) throws ServletException, LifecycleException, MalformedURLException{
    String webappDirLocation = "webapp/";
    Tomcat tomcat = new Tomcat();
    // Define port number for the web application
    String webPort = System.getenv("PORT");
    if (webPort == null || webPort.isEmpty()) {
        webPort = "8089";
    }
    // Bind the port to Tomcat server
    tomcat.setPort(Integer.valueOf(webPort));

    // Define a web application context.
    Context context = tomcat.addWebapp("/tomcatembedded", new File(
            webappDirLocation).getAbsolutePath());

    Tomcat.addServlet(context, "jersey-container-servlet", resourceConfig());
    context.addServletMapping("/rest/*", "jersey-container-servlet");


    tomcat.start();
    tomcat.getServer().await();
}
private static ServletContainer resourceConfig(){
    return new ServletContainer(
            new ResourceConfig(
                new ResourceLoader().getClasses()
            )
            .register(new ApplicationBinder()) //binds AuthenticationManager
            .packages("com.dockerhosting.api.rest.auth", "com.dockerhosting.rest.auth")
    );
}
}

当我尝试将 json 序列化的 ApiCredentials 发布到它回复的其余服务时

<!DOCTYPE html><html><head><title>Apache Tomcat/8.0.22 - Error report</title><style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style> </head><body><h1>HTTP Status 415 - Unsupported Media Type</h1><div class="line"></div><p><b>type</b> Status report</p><p><b>message</b> <u>Unsupported Media Type</u></p><p><b>description</b> <u>The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.</u></p><hr class="line"><h3>Apache Tomcat/8.0.22</h3></body></html>

我尝试将 mimepull 添加到服务的类路径并将 Content-Type 标头添加到客户端,但它没有改变任何东西。客户端代码为:

JerseyClient client = new JerseyClientBuilder().build();

    JerseyWebTarget target = client.target("http://192.168.122.156:8089/tomcatembedded/rest/auth/login");
    Response response = target.request()
            .header("Content-Type", "application/json;charset=UTF-8")
            .accept(MediaType.APPLICATION_JSON)
            .post(Entity.entity(credentials, MediaType.APPLICATION_JSON));
    String output = response.readEntity(String.class);
    System.out.println(output);

有什么想法吗?

谢谢

【问题讨论】:

  • ApiCredentials credentials 更改为String credentials 看看是否有效。如果是这样,那么您缺少 JSON 提供程序。不过我对此很好奇,因为如果您没有提供者,那么客户端甚至会在不发出请求的情况下失败,给客户端上的 credentials 不是字符串(看不到)
  • 如果这是问题所在,如果您使用的是 Maven,请参阅 here,如果不是 see here
  • @peeskillet 我将凭据类型更改为String,但奇怪的是它可以工作。我将 genson 1.3、jersey-client 和 org.json:json 添加到类路径中,将凭据更改回ApiCredentials,但它仍然回复相同的错误。 BTW 客户端是一个独立的程序,与服务相比,具有不同的依赖集(现在我添加了 genson 后,jersey-client 和 json 依赖与服务几乎相同)
  • 我不使用 Genson 或 Json.org。我不知道 json.org 是否有 jax-rs 提供程序。我用杰克逊。对于 jacskon,使用第一个链接。如果 Genson 确实有提供程序,那么您可能需要在资源配置中注册它
  • 当我说提供者时,我指的是MessageBodyReaderMessageBodyWriter 的实现。您可能想举例说明来源

标签: java json rest jax-rs


【解决方案1】:

来自评论(只是为了得到答案......请参阅 cmets 进行讨论)

Artem Zhirkov:我在 ResourceConfig 中明确注册了JacksonJsonProvider,它解决了问题

【讨论】:

  • 这很奇怪,我无法科学地解释为什么这解决了我的问题(球衣服务 .jar 在本地运行时接受 PUT,但从 docker 容器运行时返回 415)但它确实存在; resourceConfig.register(JacksonJsonProvider.class); 解决了我的问题
猜你喜欢
  • 2021-07-16
  • 2012-04-19
  • 1970-01-01
  • 2015-08-06
  • 1970-01-01
  • 2014-01-21
  • 2018-06-10
  • 1970-01-01
相关资源
最近更新 更多