Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream closed exception is RestTemplate Java. How to pass multiplte objects to Java RestClient

I am getting an unexpected error java.io.IOException: Stream closed

Error starts from this line

public void createPo(String username, PurchaseOrderDto po, List<PoItemDto> items) {
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("poDto", po);
    params.put("items", items);
    rc.post(String.format("/po?username=%s", username), params);
}

rc is the rest client which calls the api from another server. Here is its code of its post function

protected void post(String path, Object object) {
restTemplate.postForObject((url + path), object, Void.class);
}

Following is the api which handles the above request PoController.java

@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/po", method = RequestMethod.POST)
public void createPo(@RequestParam("username") String buyerId, @RequestBody PurchaseOrderDto poDto, @RequestBody List<PoItemDto> items) {
    poService.createPo(buyerId, poDto, items);
}

Logs from the tomcat server handling the request:

[http-bio-9080-exec-6]  ERROR ib.pms.controller.PoController - Stream closed java.io.IOException: Stream closed
    at org.apache.catalina.connector.InputBuffer.readByte(InputBuffer.java:301)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:106)
    at java.io.FilterInputStream.read(FilterInputStream.java:83)
    at java.io.PushbackInputStream.read(PushbackInputStream.java:139)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:168)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:105)

I can't make any sense out of this. Is there a cleaner way to pass parameters to the restApi?

like image 786
Paras Diwan Avatar asked Aug 08 '26 21:08

Paras Diwan


1 Answers

You have two @RequestBody, it's not possible, you should have one object Foo (implementing Serializable) containing PurchaseOrderDto po, List<PoItemDto> items and then passing Foo in your restTemplate.postForObject.

So, your controller has to be changed for something like:

@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/po", method = RequestMethod.POST)
public void createPo(@RequestParam("username") String buyerId, @RequestBody Foo foo) {
    poService.createPo(buyerId, foo.getDoDto(), foo.getItems());
}

I'm not sure it's going to fix your issue but at least it's one problem less

If you want to send multiple objects, you still can use a List: @RequestBody List<Foo> foos

like image 156
Emilien Brigand Avatar answered Aug 11 '26 09:08

Emilien Brigand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!