Question

I saw in the rest service the following code snippet

    @POST
    @Consumes("application/xml")
    @Path("/ProjectConfiguration/{onetimetoken}")
    public void createProjectConfiguration(@PathParam("onetimetoken") String oneTimeToken,
            CreateProjectConfigurationRequest request) throws IntegratedAppFault {
        // NOOPS
    }

In this value of variable oneTimeToken is initialised by what comes in path. But my doubt is how request object of the type CreateProjectConfigurationRequest is initialized .How are we given freedom to have any parameter in these methods . How this works ? How is it guaranteed that this gets initialised .

Était-ce utile?

La solution

The method above is expecting an HTTP POST request with an XML message in the body. You can tell because the method is annotated with @POST and @Consumes("application/xml"). Resteasy sees that you have a CreateProjectConfigurationRequest type in your method signature, which is annotated with JAXB annotations, and binds the body of your HTTP request to that object.

You can also inject instances of the following classes using the @Context annotation.

  1. javax.ws.rs.core.HttpHeaders
  2. javax.ws.rs.core.UriInfo
  3. javax.ws.rs.core.Request
  4. javax.servlet.HttpServletRequest
  5. javax.servlet.HttpServletResponse
  6. javax.servlet.ServletConfig
  7. javax.servlet.ServletContext
  8. javax.ws.rs.core.SecurityContext

There is standard support built into JAX-RS compliant frameworks for marshalling XML and Json request bodies into method arguments. If you need to read a custom message format then you would create a MessageBodyReader which would take the incoming http request body and bind it to a parameter just like XML or Json.

Example

The code below illustrates how to bind the request body to a java object in your method parameters.

Using your example above let's assume we have the following rest endpoint exposed by our service:

@POST
@Consumes("application/xml")
@Path("/ProjectConfiguration/{onetimetoken}")
public void createProjectConfiguration(@PathParam("onetimetoken") String oneTimeToken,
        CreateProjectConfigurationRequest request) throws IntegratedAppFault 
{
    System.out.println(oneTimeToken);
    System.out.println(request.toString());
}

This endpoint is expecting to receive an HTTP POST message containing an XML representation of CreateProjectConfigurationRequest.

We know this because:

  1. The method is annotated with @POST indicating it is triggered by POST requests.
  2. The method is annotated with @Consumes(application/xml) indicating that it is only triggered by requests with an HTTP Content-Type header of application/xml.
  3. There is a method parameter of CreateProjectConfigurationRequest that is not annotated with @Form, @FormParam, @PathParam, @QueryParam, or @HeaderParam that would indicate it is coming from some other part of the request.

Now, let's assume that CreateProjectConfigurationRequest is defined as follows:

@XmlRootElement
public class CreateProjectConfigurationRequest 
{
   private int id;
   private String name;

   @XmlElement
   public int getId()
   {
      return id;
   }

   public void setId(int id)
   {
      this.id = id;
   }

   @XmlElement
   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
}

Now when we send an HTTP POST request to http://somehost/someapp/ProjectConfiguration/123abc with a Content-Type of application/xml and the following XML body our method will be invoked.

<CreateProjectConfigurationRequest>
  <id>123</id>
  <name>test</name>
</CreateProjectConfigurationRequest>

The Resteasy JAXB Provider will then take the incoming XML and create a CreateProjectConfigurationRequest object based on introspecting the object and the annotations that we added to it above.

Your method will then run and print the oneTimeToken (retrieved from the path using the @PathParam("onetimetoken") annotation) and request.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top