获取Spring Boot Restful Web服务中的Mapping和Pain JSON文本。

huangapple go评论78阅读模式
英文:

Get both Mapping and Pain Json text in Spring Boot Restful webService

问题

@RequestMapping(value = "/GetDriverDetails", method = RequestMethod.POST)
public ResponseEntity<Vehicle> GetVehicleDetails(@RequestBody Vehicle vehicle, HttpServletRequest request) {
    System.out.println(vehicle);
    String json;
    if ("POST".equalsIgnoreCase(request.getMethod())) {
        try {
            ContentCachingRequestWrapper request1 = new ContentCachingRequestWrapper(request);
            String collect = request1.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            System.out.println(collect);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    return new ResponseEntity<Vehicle>(HttpStatus.OK);
}

Json request Body

{
    "vehicleName": "Brio",
    "vehicleModel": "fisrtClass",
    "drivers": [
        {
            "name": "rej",
            "licenseNumber": "KLLicense1"
        },
        {
            "name": "Dan",
            "licenseNumber": "KLLicense2"
        },
        {
            "name": "bala",
            "licenseNumber": "KLLicense3"
        },
        {
            "name": "vijay",
            "licenseNumber": "KLLicense4"
        },
        {
            "name": "aravind",
            "licenseNumber": "KLLicense5"
        },
        {
            "name": "sathya",
            "licenseNumber": "KLLicense6"
        }
    ]
}

Exception

java.io.IOException: Stream closed
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:359) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:132) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
    at org.springframework.web.util.ContentCachingRequestWrapper$ContentCachingInputStream.read(ContentCachingRequestWrapper.java:254) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297) ~[na:na]
    at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339) ~[na:na]
    at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188) ~[na:na]
    at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181) ~[na:na]
英文:

i am trying to parse json body request coming in for a post request using Spring Boot. I would like to map the body to fields on vehicle class and also to store plain json body to some variable as well for future use. But i am always getting stream closed exception when trying to access plain json body. Can someone help me out on this. Thanks In Advance

Code

@RequestMapping(value = &quot;/GetDriverDetails&quot;, method = RequestMethod.POST)
public ResponseEntity&lt;Vehicle&gt; GetVehicleDetails(@RequestBody Vehicle vehicle, HttpServletRequest request) {
	System.out.println(vehicle);
	String json;
	if (&quot;POST&quot;.equalsIgnoreCase(request.getMethod())) 
	{
	  try {
		  ContentCachingRequestWrapper request1 = new ContentCachingRequestWrapper(request);
		String collect = request1.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
		System.out.println(collect);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
    
	return new ResponseEntity&lt;Vehicle&gt;(HttpStatus.OK);
}

Json request Body

{
    &quot;vehicleName&quot;: &quot;Brio&quot;,
    &quot;vehicleModel&quot;: &quot;fisrtClass&quot;,
    &quot;drivers&quot;: [
        {
            &quot;name&quot;: &quot;rej&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense1&quot;
        },
        {
            &quot;name&quot;: &quot;Dan&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense2&quot;
        },
        {
            &quot;name&quot;: &quot;bala&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense3&quot;
        },
        {
            &quot;name&quot;: &quot;vijay&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense4&quot;
        },
        {
            &quot;name&quot;: &quot;aravind&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense5&quot;
        },
        {
            &quot;name&quot;: &quot;sathya&quot;,
            &quot;licenseNumber&quot;: &quot;KLLicense6&quot;
        }
    ]
}

Exception

java.io.IOException: Stream closed
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:359) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:132) ~[tomcat-embed-core-9.0.38.jar:9.0.38]
at org.springframework.web.util.ContentCachingRequestWrapper$ContentCachingInputStream.read(ContentCachingRequestWrapper.java:254) ~[spring-web-5.2.9.RELEASE.jar:5.2.9.RELEASE]
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:297) ~[na:na]
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339) ~[na:na]
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:188) ~[na:na]
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:181) ~[na:na]

答案1

得分: 1

以下是翻译好的代码部分:

解决方案针对您的主要问题,由于您正在使用 @RequestBody,内容已经被读取并映射到了 POJO 类,因此在这种情况下流已被使用并关闭,您不需要使用 @RequestBody。请在下面找到我的实现:

 @PostMapping(path = "update-vehicle-details", consumes = MediaType.ALL_VALUE)
public VehicleDriver updateVehicleDetails(HttpServletRequest request) throws IOException {
    ContentCachingRequestWrapper request1 = new ContentCachingRequestWrapper(request);
    String collect = request1.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
    System.out.println(collect);
    final VehicleDriver vehicleDriver = new ObjectMapper().readValue(collect, VehicleDriver.class);
    return vehicleDriver;
}

另外,您也可以使用简单的方法,从应用程序 JSON 内容类型中读取值,在 requestbody 中进行解析,并将该正文转换为字符串,然后返回相同的结果:

@RestController
public static class TestController {

    @PostMapping(path = "update-vehicle-details", consumes = MediaType.APPLICATION_JSON_VALUE)
    public String updateVehicleDetails(@RequestBody VehicleDriver vehicleDriver) throws JsonProcessingException {
        final StringBuilder stringBuilder = new StringBuilder(vehicleDriver.vehicleName);
        List<String> driverDetails = Optional.ofNullable(
                vehicleDriver.drivers)
                .map(Collection::stream)
                .orElse(Stream.empty())
                .map(d -> "name=: " + d.name + ", license number:" + d.licenseNumber)
                .collect(Collectors.toList());
        stringBuilder.append("\n");
        stringBuilder.append(driverDetails);
        String stringRepresentationOfBody = new ObjectMapper().writeValueAsString(vehicleDriver);
        return stringRepresentationOfBody;
    }

}

public static class VehicleDriver {
    public String vehicleName;
    public String vehicleModel;
    public List<Driver> drivers;
}

public static class Driver {
    public String name;
    public String licenseNumber;
}
英文:

Can you try following code:

The solution to your main problem, since you are using @RequestBody, contents are already read and mapped to pojo class hence stream is utlized and closed in this case you do not want to use @RequestBody at all. Please find my implementation below:

 @PostMapping(path = &quot;update-vehicle-details&quot;, consumes = MediaType.ALL_VALUE)
        public VehicleDriver updateVehicleDetails(HttpServletRequest request) throws IOException {
            ContentCachingRequestWrapper request1 = new ContentCachingRequestWrapper(request);
            String collect = request1.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
            System.out.println(collect);
            final VehicleDriver vehicleDriver = new ObjectMapper().readValue(collect, VehicleDriver.class);
            return vehicleDriver;
        }

Otherwise, use a simple approach, read the value from application json content type parses in requestbody and converts that body to string and return the same result

@RestController
    public static class TestController {

        @PostMapping(path = &quot;update-vehicle-details&quot;, consumes = MediaType.APPLICATION_JSON_VALUE)
        public String updateVehicleDetails(@RequestBody VehicleDriver vehicleDriver) throws JsonProcessingException {
            final StringBuilder stringBuilder = new StringBuilder(vehicleDriver.vehicleName);
            List&lt;String&gt; driverDetails = Optional.ofNullable(
                    vehicleDriver.drivers)
                    .map(Collection::stream)
                    .orElse(Stream.empty())
                    .map(d -&gt; &quot;name=: &quot; + d.name + &quot;, license number:&quot; + d.licenseNumber)
                    .collect(Collectors.toList());
            stringBuilder.append(&quot;\n&quot;);
            stringBuilder.append(driverDetails);
            String stringRepresentationOfBody = new ObjectMapper().writeValueAsString(vehicleDriver);
//            return stringBuilder.toString();
            return stringRepresentationOfBody;
        }

    }

    public static class VehicleDriver {
        public String vehicleName;
        public String vehicleModel;
        public List&lt;Driver&gt; drivers;
    }

    public static class Driver {
        public String name;
        public String licenseNumber;
    }

答案2

得分: 0

尝试使用对象映射器将您的车辆对象转换为 JSON 字符串,在这种情况下,您将不需要方法参数中的请求。
并且您正在使用 POST 请求方法,因此不需要 if 条件。

英文:

Try using Object Mapper for converting your vehicle object to json string and in that case you would not be needing request in method argument.
And you are using post request method then if condition is not needed.

huangapple
  • 本文由 发表于 2020年10月14日 02:51:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/64341417.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定