使用ClientBuilder发送JSON正文但使用ContentType = application / x-www-form-urlencoded

时间:2016-04-24 13:13:32

标签: java jax-rs

我知道这个问题很奇怪。不幸的是我有一个服务要求所有东西都有标题ContentType=application/x-www-form-urlencoded,尽管主体是JSON

我正在尝试使用JAX-RS 2.0 ClientBuilder来调用它:

String baseUrl = "http://api.example.com/";

JSONObject body = new JSONObject();
body.put("key", "value");

Client client = ClientBuilder.newClient();
client.register(new LoggingFilter());
Builder builder = client.target(baseUrl).path("something").request();

Invocation inv = builder
    .header("Content-type", MediaType.APPLICATION_FORM_URLENCODED)
    .buildPost(Entity.json(body));
Response response = inv.invoke();

int status = response.getStatus();
// I get 415, unsupported media type (in this case is unexpected)

我已经检查了我的日志,但是当我设置application/x-www-form-urlencoded时(通过MediaType),请求显然有Content-type application/json

如何强制请求获得我想要的Content-type

<小时/> 顺便说一句:这是我的自定义记录器:

public class LoggingFilter implements ClientRequestFilter {
    private static final Logger LOG = Logger.getLogger(LoggingFilter.class.getName());

    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        LOG.log(Level.INFO, "body");
        LOG.log(Level.INFO, requestContext.getEntity().toString());
        LOG.log(Level.INFO, "headers");
        LOG.log(Level.INFO, requestContext.getHeaders().toString());
    }
}

这些是我得到的日志:

com.acme.LoggingFilter                   I body
com.acme.LoggingFilter                   I {"key":"value"}
com.acme.LoggingFilter                   I headers
com.acme.LoggingFilter                   I {Content-type=[application/json]}

1 个答案:

答案 0 :(得分:1)

尝试使用其中一个静态Entity辅助方法的问题是它会覆盖您可能设置的任何先前的Content-Type标头。在目前的情况下,Entity.json会自动将标头设置为application/json

您可以只使用通用.json方法,而不是使用Entity.entity(Object, MediaType)方法。但是,根据您当前的情况,您可以执行Entity.entity(body, MediaType.APPLICATION_FORM_URLENCODED_TYPE)。原因是客户端将寻找知道如何序列化JSONObjectapplication/x-www-form-urlencoded数据的提供者,而这些数据没有。因此,您需要先将其序列化为String。这样,处理application/x-www-form-urlencoded的提供程序不需要序列化任何内容。所以就这样做

Entity.entity(body.toString(), MediaType.APPLICATION_FORM_URLENCODED_TYPE);