java @Consumes(MediaType.APPLICATION_FORM_URLENCODED) FormParameter 为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25259760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:41:36  来源:igfitidea点击:

@Consumes(MediaType.APPLICATION_FORM_URLENCODED) FormParameter is null

javaweb-serviceshttpjerseyjax-rs

提问by

I've created a Jersey webservice that looks like this:

我创建了一个如下所示的 Jersey 网络服务:

@Path("/webhookservice")
public class Webhook {

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response readData(@FormParam("payload") Payload payload, @Context HttpServletRequest req) {

        // Gets client IP address
        String ipAddress = (req.getRemoteHost().equals("") || req.getRemoteHost() == null) ? "UNKNOWN" : req.getRemoteHost();

        // Persist data to DB
        Persist.saveToDb(payload.getId(), Integer.toString(payload.getTimestamp()),
                payload.getStatus(), payload.getAuth_code(),
                payload.getTotal_amount(), payload.getRequired_amount(),
                ipAddress);

        // Repsond with a HTTP 200 OK
        Response response = Response.status(200).build();
        return response;

    }

    @GET
    @Produces("text/plain")
    public String testService() {
        return "Service is up and working!";
    }

}

The Payload class looks like this:

Payload 类如下所示:

@XmlRootElement
public class Payload {

    private String id;
    private int timestamp;    
    private String status;    
    private String auth_code;    
    private int total_amount;    
    private int required_amount;

    // Getters
    @XmlElement(name = "id")
    public String getId() {
        return this.id;
    }

    @XmlElement(name = "timestamp")
    public int getTimestamp() {
        return this.timestamp;
    }

    @XmlElement(name = "status")
    public String getStatus() {
        return this.status;
    }

    @XmlElement(name = "auth_code")
    public String getAuth_code() {
        return this.auth_code;
    }

    @XmlElement(name = "total_amount")
    public int getTotal_amount() {
        return this.total_amount;
    }

    @XmlElement(name = "required_amount")
    public int getRequired_amount() {
        return this.required_amount;
    }

    // Setters
    public void setId(String id) {
        this.id = id;
    }

    public void setTimestamp(int timestamp) {
        this.timestamp = timestamp;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void setAuth_code(String auth_code) {
        this.auth_code = auth_code;
    }

    public void setTotal_amount(int total_amount) {
        this.total_amount = total_amount;
    }

    public void setRequired_amount(int required_amount) {
        this.required_amount = required_amount;
    }

}

And the request that I'm sending looks like this:

我发送的请求如下所示:

Content-Type: application/x-www-form-urlencoded Method: POST

内容类型:application/x-www-form-urlencoded 方法:POST

Unencodedbody:

未编码的正文:

payload={"id":"123123","auth_code":"191331","required_amount":101,"timestamp":1407775713,"status":"completed","total_amount":101}

Encodedbody:

编码体:

payload%3D%7B%22id%22%3A%22123123%22%2C%22auth_code%22%3A%22191331%22%2C%22required_amount%22%3A101%2C%22timestamp%22%3A1407775713%2C%22status%22%3A%22completed%22%2C%22total_amount%22%3A101%7D

But when I send the request off the 'payload' object is null in my 'readData()' function in the 'Webhook' class... Can anybody point me in the right direction?

但是,当我在“Webhook”类的“readData()”函数中发送请求时,“payload”对象为空……有人能指出我正确的方向吗?

采纳答案by Andrei I

Try using a @Consumes(MediaType.APPLICATION_XML)(also set it when you send the request) and then remove the @FormParam("payload")annotation. When you send the payload in your client, make sure it is XML encoded (without payload=).

尝试使用 a @Consumes(MediaType.APPLICATION_XML)(在发送请求时也设置它),然后删除@FormParam("payload")注释。当您在客户端中发送有效负载时,请确保它是 XML 编码的(没有payload=)。

Otherwise, if you want to stick with your schema (mixing MediaType.APPLICATION_FORM_URLENCODED with XML) you will have to decode manually the encoded XML String. What I mean is the following:

否则,如果您想坚持使用您的架构(将 MediaType.APPLICATION_FORM_URLENCODED 与 XML 混合),您将必须手动解码编码的 XML 字符串。我的意思是:

@Path("/webhookservice")
public class Webhook {

    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response readData(@FormParam("payload") String payload, @Context HttpServletRequest req) {
        JAXBContext jaxbContext = JAXBContext.newInstance(Payload.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

        StringReader reader = new StringReader(payload,);
        Payload payload = (Payload) unmarshaller.unmarshal(reader);

        //...
    }
}

Why you must work with a String instead of a Payload parameter? Because noone tells Jersey/JAX-RS how to decode that String: it may be a JSON String, or an XML String.

为什么必须使用 String 而不是 Payload 参数?因为没有人告诉 Jersey/JAX-RS 如何解码该字符串:它可能是一个 JSON 字符串,或一个 XML 字符串。

回答by

I've done it like this, and it's working:

我已经这样做了,它正在工作:

    @Path("users")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_JSON)
    public Login postLogin( MultivaluedMap<String, String> personParams ) {
        String user = personParams.getFirst(USER);
        String pass = personParams.getFirst(PASSWORD);