问题
I am learning Jersey webservices and came across the usage of @Produces, so to understand it I have written a small program like this:
@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
public class UserResource {
@GET
@Produces("text/plain")
public String getUser(@PathParam("username") String userName) {
return "Hello " + userName;
}
@GET
@Produces({"application/xml", "application/json"})
public String doGetAsXmlOrJson(@PathParam("username") String userName) {
return "<text>Hello World</text>";
}
}
When I pass the request as http://localhost:9998/users/Java, along with the header as "Accept : application/json" then I was expecting the output to be <text>Hello World</text>. But instead of that I am getting it as Hello Java. I am testing this using Chrome browser's Postman client.
Now if I remove the getUser method in above program then I get the output as <text>Hello World</text>.
Can you please tell me why even when I set the Accept header, the request is not going to my doGetAsXmlOrJson method?
Update: Adding more details -
The program is deployed using below code as mentioned in Jersey documentation:
import java.io.IOException;
import java.net.URI;
import javax.ws.rs.core.UriBuilder;
import org.glassfish.grizzly.http.server.HttpServer;
import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
public class Main {
private static URI getBaseURI() {
return UriBuilder.fromUri("http://localhost/").port(9998).build();
}
public static final URI BASE_URI = getBaseURI();
protected static HttpServer startServer() throws IOException {
System.out.println("Starting grizzly...");
ResourceConfig rc = new PackagesResourceConfig("com.examples.Jersey1");
return GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
}
public static void main(String[] args) throws IOException {
HttpServer httpServer = startServer();
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nTry out %shelloworld\nHit enter to stop it...",
BASE_URI, BASE_URI));
System.in.read();
httpServer.stop();
}
}
This is how I am testing using Postman client:
回答1:
I didn't know you can have 2 "@GET" for the same @Path. I guess one could assume jersey will route it to the right method based of "accepts" header.
I understand this is a test, but I don't know how useful is a text representation of an object.
Here's how and when I use @Produces
Typically, my web services will either serve XML or JSON. Any typical services would produces both, according to the client preference (using the accept header), as per your doGetAsXmlOrJson method
You don't need to produce the XML or the JSON yourself, just return a POJO, and Jersey will use Jackson or Moxy (or your favorite JSON / XML provider as configured with Jersey) to convert it for you, outputing JSON or XML based of your "accepts" header.
Sometimes, some services may return images, pdf, or even text :) ... and in these specials cases, I use the other possible values of @Produces...
But I never add a case where I wanted automatic JSON/XML marshalling or text.. I guess it could be useful for debugging, but JSON and XML are usually human readable.
来源:https://stackoverflow.com/questions/31522824/using-produces-for-different-methods