@Consumes(MediaType.APPLICATION_FORM_URLENCODED) FormParameter is null
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=
).
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:
@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.
Admin
Updated on August 13, 2020Comments
-
Admin over 3 years
I've created a Jersey webservice that looks like this:
@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:
@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
Unencoded body:
payload={"id":"123123","auth_code":"191331","required_amount":101,"timestamp":1407775713,"status":"completed","total_amount":101}
Encoded body:
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?
-
Admin over 9 yearsI'm writing a webhook that received data from an outside company and they're not willing to change they request body type to application/xml. It has to stay application/x-www-form-urlencoded
-
V G over 9 yearsNo problems. If you must stick with that, I added more details in my answer. But I consider those guys do not really know what they do: the payload is probably the only thing that is sent with such a request, so it is not needed to put in a FormParam.
-
V G over 9 years@Relborg did you try my solution?
-
Admin over 9 yearsAh yes! Thanks :-) I did use another JSON parsing library though. But yes it worked, thank you!