Search code examples
javajsonjerseygsonpayara

Bad Request from Jersey server endpoint


I've been looking at a problem which happens when I submit a request;

X-Forwarded-For: so.me.ip.ad
Authorization: Bearer blahblahblahstuff
Accept: application/json
Content-Type: application/json; charset=UTF-8
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.8.0_60
Host: the.endpoint.io
Connection: keep-alive
Content-Length: 395 

with a syntactically correct Gson json body. It's exactly the same length, and well formed. I used wireshark to capture the exact response and the numbers add up. ie, I don't think there's bloat on the end of the request body. Please tell me if wireshark wouldn't be able to pick this up. Considering this, I don't think the fix here would be applicable to this issue.

I've been testing it locally running payara, and the production server is also payara (exact same version). Locally, the request is fine, works as expected, using exactly the same params live, the endpoint isn't reached, as we handle our own api error codes, and this one is given in html, not json, and can be seen below;

Payara Server 4.1.2.173 #badassfish - Error report

HTTP Status 400 - Bad Request


type: Status report

message: Bad Request

description: The request sent by the client was syntactically incorrect.


Payara Server 4.1.2.173 #badassfish

We are using the HttpUrlConnection library execute the post;

        URL url = new URL(uri);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        if (this.clientip != null && !this.clientip.isEmpty())
        {
            connection.addRequestProperty("X-Forwarded-For", this.clientip);
        }
        if (this.vauthtoken != null && !this.vauthtoken.isEmpty())
        {
            connection.addRequestProperty("Authorization", "Bearer " + this.vauthtoken);
        }
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestMethod(this.method);
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setDoOutput(true);

        if(this.body != null)
        {
            try (OutputStream os = connection.getOutputStream()) {
                os.write(this.body.toString().getBytes("UTF-8"));
            }
        }

        if(connection.getResponseCode() == HttpURLConnection.HTTP_OK)
        {
            response = this.getJsonBody(connection.getInputStream());
        }
        else
        {
            response = this.getJsonBody(connection.getErrorStream());
        }

And our endpoint looks like;

@Path("/some/path")
public class SomeClass extends SomeThingelse {

    final static Logger LOGGER = Logger.getLogger(SomeClass.class.getName());

    @POST
    @Audit
    @Secured(roles = {Role.SOMEROLE}, crud = Crud.CREATE)
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response someMethodRelating(@Context SecurityContext securityContext, @Valid SomeValidatedClass svClass)
    {

Have I missed something? Or is this more of a server issue? Any help would be greatly appreciated thank you.


Solution

  • Either you are not using the correct method (using GET instead of POST), or the body you are sending is not JSON or does not validate the rules that are in SomeValidatedClass.