1

I created a simple GrizzlyHttpServerFactory.createHttpServer service and trying to issue a @GET operation, where the client would pass in arguments, however I am receiving an error:

enter image description here

I perused several examples and everything looks fine. Everything works, so long as I do not try and pass parameters. Here is the code that I have so far.

in main()

final ResourceConfig resourceConfig = new ResourceConfig(TestServerResource.class);
final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create("http://localhost:8081/base/"), resourceConfig);

In Resource Class:

@Path("TestServer")
public class TestServerResource
{
    public static final String CLICHED_MESSAGE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<note>\r\n<to>Tove</to>\r\n<from>Jani</from>\r\n<heading>Reminder</heading>\r\n<body>Don't forget me this weekend!</body>\r\n</note>\r\n\r\n";
    public static final String DO_MESSAGE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<DoTask>\r\n\t<Response>%s</Response>\r\n</DoTask>\r\n\r\n";

    @GET
    @Path("getHello")
    @Produces(MediaType.APPLICATION_XML)
    public String getHello()
    {
        return CLICHED_MESSAGE;
    }

    @GET
    @Path("testGet3")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces(MediaType.APPLICATION_XML)
    public String testGet3(MultivaluedMap<String, String> formParams)
    {
        // Get the parameters.
        String argTitle = formParams.getFirst("title");
        String argAuthor = formParams.getFirst("author");

        // Create the XML response.
        String xmlResponse = String.format(DO_MESSAGE, String.format("Book Title %s with author %s", argTitle, argAuthor));

        return xmlResponse;
    }
}

After service running on my CentOS 7 box. Here is terminal command.

Works (no parameters):

[test@Turbo Downloads]$ curl -H "Accept: application/xml" "http://localhost:8081/base/TestServer/getHello"
<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

With parameters does NOT work:

[test@Turbo Downloads]$ curl -H "Accept: application/xml" "http://localhost:8081/base/TestServer/testGet3?title=smurfs&author=Gargamel"
<html><head><title>Grizzly 2.3.8</title><style><!--div.header {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#003300;font-size:22px;-moz-border-radius-topleft: 10px;border-top-left-radius: 10px;-moz-border-radius-topright: 10px;border-top-right-radius: 10px;padding-left: 5px}div.body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:#FFFFCC;font-size:16px;padding-top:10px;padding-bottom:10px;padding-left:10px}div.footer {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#666633;font-size:14px;-moz-border-radius-bottomleft: 10px;border-bottom-left-radius: 10px;-moz-border-radius-bottomright: 10px;border-bottom-right-radius: 10px;padding-left: 5px}BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;}B {font-family:Tahoma,Arial,sans-serif;color:black;}A {color : black;}HR {color : #999966;}--></style> </head><body><div class="header">Request failed.</div><div class="body">Request failed.</div><div class="footer">Grizzly 2.3.8</div></body></html>[test@Turbo Downloads]$ 

I did wrap the url in quotes, when passing arguments, so that is not the problem. Thoughts?

Here are just a few of the resources that I perused:

  • Resources 1, 2, 3, 4

Specifying a header to curl with the -H does not matter seem to matter in this particular example, when not using arguments, as I tried both ways and I get the proper XML back. I do not have to specify the -X option, as GET is the default operation, which is what I am specifying. Single and double quotes yield the same result.

I tried to implement GrizzlyWebContainerFactory, as mentioned in 24518607, but I could not get ant to locate that jar, even though Eclipse was happy enough. I did not want to get side tracked, so I stayed focused.

Thoughts?

Community
  • 1
  • 1
Sarah Weinberger
  • 15,041
  • 25
  • 83
  • 130
  • Wild guess but I would guess it has to do with `@GET`. Generally, GET should not have a body. I know that before Grizzly didn't support allowing a body for DELETE (not sure about GET), but it could be configured to allow it (maybe same configuration for GET). But anyway, to stay true to semantics, use POST. Change the method the `@POST` and add `-X POST` to the `curl` command. See what happens. – Paul Samsotha Nov 06 '15 at 23:54
  • @peeskillet Same problem. I forgot to add that I tried adding system.out.println() messages in the testGet3 call, but those never showed. Grizzly never called the method, so Grizzly does not like either the curl statement or the format of the method. – Sarah Weinberger Nov 07 '15 at 00:04
  • 1
    Ahh I see. You are trying to pass the data in the query string. I didn't notice that. On the server you are expecting it as the body. I would imagine you are getting an NPE ('cause there is no body) which is getting swallowed by Jersey and sent out as a 500, which Grizzly returns as what you see. So to fix, use `@POST`, `-X POST` and instead of putting the data in the URL, use `-d title=smurf -d author=Gargamel` – Paul Samsotha Nov 07 '15 at 00:17
  • For problems like this (where there is no useful error message), the first step I generally take is to create an `ExceptionMapper` that I register. Often there is some exception that is being swallowed by Jersey and it get wrapped in some Jersey exception which leads to a useless 500 with no message of the real problem. With the `ExceptionMapper`, in most cases it should see the real exception, and could at least print the stack trace. See [here](https://jersey.java.net/documentation/latest/representations.html#d0e6653) for info about the `ExceptionMapper` – Paul Samsotha Nov 07 '15 at 00:21
  • 1
    And just FYI, if you wanted to go with GET and send the data in the URL, I would first get rid of the `@Consumes`, as that implies you are expecting a request body (it's just confusing), then if you want the `MultivaluedMap` of the query parameters, you can inject `@Context UriInfo` into the method, then call `uriInfo.getQueryParameters()`, which will return the `MultivaluedMap` of the query parameters. Or individually use `@QueryParam("title") String title` for each param – Paul Samsotha Nov 07 '15 at 00:24
  • @peeskillet Thank you. I will look at that. You were right on the problem. The -d solved the problem. I do want to pass parameters via the URL, so I will try your suggestion. – Sarah Weinberger Nov 07 '15 at 00:26
  • @peeskillet Yay! (By the way, how did you get code grayed in a comment?) Here is the working modified method: public String testGet4(@Context UriInfo oUriInfo) { ... } – Sarah Weinberger Nov 07 '15 at 00:35

1 Answers1

1

First your resource method is expecting data in the request body, for that it should be changed to @POST, then in curl command use

curl -X POST "http://localhost:8081/base/TestServer/testGet3"
     -d "title=smurfs" -d "author=Gargamel"

If you wanted to keep the data in the URL with GET, then you should change you resource method to the following

@GET
@Path("testGet3")
@Produces(MediaType.APPLICATION_XML)
public String testGet3(@Context UriInfo uriInfo)
{
    MultivaluedMap<String, String> params 
            = uriInfo.getQueryParameters();
}

Or you can list each query parameter individually with @QueryParam

public String testGet3(@QueryParam("title") String title,
                       @QueryParam("author") String author)

As an aside, for problems like this (where there is no useful error message), the first step I generally take is to create an ExceptionMapper<Throwable> that I register. Often there is some exception that is being swallowed by Jersey and it get wrapped in some Jersey exception which leads to a useless 500 with no message of the real problem. With the ExceptionMapper, in most cases it should see the real exception, and could at least print the stack trace. See here for info about the ExceptionMapper

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720