Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print request body using spring-test-mvc

I'm using spring-test-mvc to test my controller, but I can't find a way to print request body which is very inconvenient.

with MockMvcResultHandlers.print()

mvc.perform(put("/payment/1234")
    .content("{\"amount\":2.3")
    .contentType(MediaType.APPLICATION_JSON))
    .andDo(print());

I found some body information but don't find the body part:

MockHttpServletRequest:
     HTTP Method = PUT
     Request URI = /payment/1234
      Parameters = {}
         Headers = {Content-Type=[application/json]}

         Handler:
            Type = com.restbucks.ordering.rest.PaymentResource
          Method = public org.springframework.hateoas.Resource<com.restbucks.ordering.domain.Payment> com.restbucks.ordering.rest.PaymentResource.handle(com.restbucks.ordering.commands.MakePaymentCommand)

           Async:
   Async started = false
    Async result = null

Update

After reading some source codes, it seems that I should extends MockMvcResultHandlers to add some print items?

//PrintingResultHandler.java
protected void printRequest(MockHttpServletRequest request) throws Exception {
    this.printer.printValue("HTTP Method", request.getMethod());
    this.printer.printValue("Request URI", request.getRequestURI());
    this.printer.printValue("Parameters", getParamsMultiValueMap(request));
    this.printer.printValue("Headers", getRequestHeaders(request));
    // add body print?
}

Update Proof of Concept codes:

public static class CustomMockMvcResultHandlers {

    public static ResultHandler print() {
        return new ConsolePrintingResultHandler();
    }


    /**
     * Have to copy this class from spring
     */
    private static class ConsolePrintingResultHandler extends PrintingResultHandler {

        public ConsolePrintingResultHandler() {
            super(new ResultValuePrinter() {

                @Override
                public void printHeading(String heading) {
                    System.out.println();
                    System.out.println(String.format("%20s:", heading));
                }

                @Override
                public void printValue(String label, Object value) {
                    if (value != null && value.getClass().isArray()) {
                        value = CollectionUtils.arrayToList(value);
                    }
                    System.out.println(String.format("%20s = %s", label, value));
                }


            });


        }

        @Override
        protected void printRequest(MockHttpServletRequest request) throws Exception {
            super.printRequest(request);
            getPrinter().printValue("Body", getContentAsString(request));
        }

        private String getContentAsString(MockHttpServletRequest request) throws IOException {
            BufferedReader reader = request.getReader();

            StringBuilder builder = new StringBuilder();
            String aux;

            while ((aux = reader.readLine()) != null) {
                builder.append(aux);
            }

            return builder.toString();
        }
    }
}
like image 910
Yugang Zhou Avatar asked Oct 08 '15 10:10

Yugang Zhou


People also ask

What is the@ RequestBody annotation?

Simply put, the @RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.

How do you read a body request in spring boot?

To retrieve the body of the POST request sent to the handler, we'll use the @RequestBody annotation, and assign its value to a String. This takes the body of the request and neatly packs it into our fullName String.

What is @RequestBody annotation in spring boot?

Annotation Type RequestBody Annotation indicating a method parameter should be bound to the body of the web request. The body of the request is passed through an HttpMessageConverter to resolve the method argument depending on the content type of the request.

What is MockHttpServletRequestBuilder?

public MockHttpServletRequestBuilder servletPath(String servletPath) Specify the portion of the requestURI that represents the path to which the Servlet is mapped. This is typically a portion of the requestURI after the context path.


1 Answers

I believe this will now be possible with Spring Framework 5.0 M3:

The print() and log() methods in Spring MVC Test now print the request body if the character encoding has been set in the mock request.

Based on this Jira ticket

Also mentioned in the release notes

like image 167
Poly Avatar answered Oct 19 '22 04:10

Poly