Java request entity example

Spring MVC — Using RequestEntity and ResponseEntity

org.springframework.http.RequestEntity extends HttpEntity and adds additional information of HTTP method and uri to the request.

org.springframework.http.ResponseEntity also extends HttpEntity, where we can add additional HttpStatus (see also @ResponseStatus) to the response.

In this example we are going to show the use of RequestEntity and RequestResponse with JUnit tests.

Handling request having String body

@Controller @RequestMapping public class MyController < @RequestMapping("test") public ResponseEntityhandleRequest (RequestEntity requestEntity) < System.out.println("request body : " + requestEntity.getBody()); HttpHeaders headers = requestEntity.getHeaders(); System.out.println("request headers : " + headers); HttpMethod method = requestEntity.getMethod(); System.out.println("request method : " + method); System.out.println("request url: " + requestEntity.getUrl()); ResponseEntityresponseEntity = new ResponseEntity<>("my response body", HttpStatus.OK); return responseEntity; > >

The unit test

@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = MyWebConfig.class) public class ControllerTest < @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup () < DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); this.mockMvc = builder.build(); >@Test public void testUserController () throws Exception < MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/test") .header("testHeader", "headerValue") .content("test body"); this.mockMvc.perform(builder) .andExpect(MockMvcResultMatchers.status() .isOk()) .andDo(MockMvcResultHandlers.print());

Output:

request body : test body request headers : request method : POST request url: http://localhost:80/test MockHttpServletRequest: HTTP Method = POST Request URI = /test Parameters = <> Headers = Handler: Type = com.logicbig.example.MyController Method = public org.springframework.http.HttpEntity com.logicbig.example.MyController.handleRequest(org.springframework.http.RequestEntity) Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = Content type = text/plain;charset=ISO-8859-1 Body = my response body Forwarded URL = null Redirected URL = null Cookies = []

Using Backing/Command Object

public class User implements Serializable < private Long id; private String name; private String password; private String emailAddress; //getters and setters >

The Controller

@Controller @RequestMapping public class MyController < @RequestMapping("/user") public ResponseEntityhandleUserRequest (RequestEntity requestEntity) < User user = requestEntity.getBody(); System.out.println("request body: " + user); System.out.println("request headers " + requestEntity.getHeaders()); System.out.println("request method : " + requestEntity.getMethod()); MultiValueMapheaders = new HttpHeaders(); headers.put("Cache-Control", Arrays.asList("max-age=3600")); ResponseEntity responseEntity = new ResponseEntity<>("my response body", headers, HttpStatus.OK); return responseEntity; > >

Unit Test

@RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ContextConfiguration(classes = MyWebConfig.class) public class ControllerTest < @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Before public void setup () < DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.wac); this.mockMvc = builder.build(); >@Test public void testUserController () throws Exception < MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post("/user") .header("testHeader", "headerValue") .contentType(MediaType.APPLICATION_JSON) .content(createUserInJson("joe", "joe@example.com")); this.mockMvc.perform(builder) .andExpect(MockMvcResultMatchers.status() .isOk()) .andDo(MockMvcResultHandlers.print()); >private static String createUserInJson (String name, String email) < return "< \"name\": \"" + name + "\", " + "\"emailAddress\":\"" + email + "\">"; > >

Output:

request body: User request headers request method : POST MockHttpServletRequest: HTTP Method = POST Request URI = /user Parameters = <> Headers = Handler: Type = com.logicbig.example.MyController Method = public org.springframework.http.HttpEntity com.logicbig.example.MyController.handleUserRequest(org.springframework.http.RequestEntity) Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = Content type = text/plain;charset=ISO-8859-1 Body = my response body Forwarded URL = null Redirected URL = null Cookies = []

Example Project

Dependencies and Technologies Used:

  • Spring Web MVC 4.2.4.RELEASE: Spring Web MVC.
  • Spring TestContext Framework 4.2.4.RELEASE: Spring TestContext Framework.
  • Java Servlet API 3.0.1
  • JUnit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • jackson-databind 2.7.2: General data-binding functionality for Jackson: works on core streaming API.
  • JDK 1.8
  • Maven 3.0.4

Источник

Request and Response Entities

Request and response entities represent the main part of an HTTP request. Entities are also refered to as the "message body" or "payload". Entities are sent via a request, usually an HTTP POST and PUT method are used or they are returned in a response, this is relevant for all HTTP methods.

Unlike other distributed systems technologies, there is generally no wrapper around an entity. For example, if a request is made for a binary PNG image represented here, http://example.com/user/abcd/portrait.png , the response entity is only the PNG image binary data.

Resource methods have a single entity parameter that represents the main entity body. It is the only unannotated parameter allowed in a resource method.

When using JAX-RS, request and response entites are mapped to and from Java types by Entity Providers that implement the JAX-RS interfaces, MessageBodyReader and MessageBodyWriter. Applications may provide their own MessageBodyReaders and MessageBodyWriters that take precedent over the runtime provided ones.

Media Types (MIME) and javax.ws.rs.core.MediaType

The request and response entity can be any form of data, a way of identifying what the entities bits and bytes represent is needed. In requests and responses, the Content-Type HTTP header is used to indicate the type of entity currently being sent. The Content-Type value comes from a well known media type as registered in IANA.

Common content types include "text/plain", "text/xml", "text/html", and "application/json".

Correct Content-Type values are essential for clients and servers. "Unusual" behavior by clients such as browsers can be attributed to wrong content types.

Media Types are also used in a request Accept header to indicate what type of resource representation the client wants to receive. Clients could indicate a preference as well, such as JSON before XML.

javax.ws.rs.core.MediaType has functionality and representations related to Media Types.

@Consumes and @Produces Annotations

Annotating a class or a resource method with @Consumes and @Produces will help the JAX-RS runtime identify the appropriate methods to invoke for requests. For example:

@Path("/example") public RootResource < @POST @Consumes("text/xml") @Produces("text/xml") public Response getOnlyXML(String incomingXML) < return Response.ok("only xml").type("text/xml").build(); > @GET @Produces("text/html", "text/plain") public String getText() < return "text representation"; > >

In the previous code example, if a HTTP POST to "/example" was issued with a Content-Type header of "text/xml" and an Accept header of "text/xml", then the RootResource#getOnlyXML method would be invoked. If the same POST request was issued with an Accept header of "text/plain", then a 406 Not Acceptable response would be generated by the JAX-RS runtime and the method would not be invoked.

It is a good practice to return a javax.ws.rs.core.Response with a .type() or .variant() call since it would guarantee a return content type. Notice that the above getText() code supports multiple data types. A javax.ws.rs.core.Response object returned must have a single concrete Content-Type value. In orer to select the best acceptable representation in the resource method, use either the @Context HttpHeaders#getAcceptableMediaTypes() or a @Context Request#selectVariant() method.

While resource methods may consume one media type for example XML and produce another such as JSON, most user requests expect the same media type that was sent in the request to be returned in the response.

If the Content-Type header is empty and there is an entity, then the JAX-RS runtime will make the Content-Type be "application/octet-stream". If an Accept header is empty, then according to the HTTP specification, the Accept header is equivalent to */* which is a wildcard that matches anything.

Important Note
Note that the resource method ultimately has control over the response content. If a javax.ws.rs.core.Response is returned, then the developer can return whatever Content-Type is desired. The @Consumes and @Produces is primarily useful only when processing request information and determining which resource method is possible to invoke. If a specific Response content type is not specified via a returned javax.ws.rs.core.Response object, the response media type is determined by a combination of the @Produces annotation values and the available MessageBodyWriters for the response entity's Java type. This can lead to undesired results if there is no @Produces annotation or if the @Produces annotation has multiple media types listed.

JAX-RS Standard Entity Parameter Types

JAX-RS requires certain parameters to be supported for virtually any content type. The following table lists the supported content types:

Java Type Content Type Supported Special Notes
java.lang.String */*
byte[] */*
java.io.InputStream */*
java.io.Reader */*
java.io.File */*
javax.activation.DataSource */*
javax.xml.transform.Source text/xml, application/xml, application/*+xml
javax.xml.bind.JAXBElement
and JAXB classes
text/xml, application/xml, application/*+xml
javax.ws.rs.core
.MultivaluedMap
application/x-www-form-urlencoded
javax.ws.rs
.core.StreamingOutput
*/* As a writer only

Developers can use the previous Java types as entity parameters for requests and responses.

@Path("/example") public class RootResource < @GET @Produces("text/xml") public Response getInfo() < byte[] entity = /* get the entity into a byte array */ return Response.ok(entity).type("text/xml").build(); > @POST @Consumes("application/json") @Produces("application/json") public StreamingOutput createItem(InputStream requestBodyStream) < /* read the requestBodyStream like a normal input stream */ return new StreamingOutput() < public void write(OutputStream output) throws IOException, WebApplicationException < byte[] out = /* get some bytes to write */ output.write(out); > >) > >

Transfer Encoding

Transfer or "chunked" encoding is handled by the container for incoming requests. The container or the application must do any transfer encoding for outgoing responses.

Content Encoding

Content for example "gzip" and or "deflate" encoding is handled by the application. However, some containers handle content encoding for developers and will uncompress content automatically or will with various configuration set. Check the container documentation.

Источник

Читайте также:  Join two arrays php
Оцените статью