Can any please tell me how can I call following service method with RestTemplate. Thanks.
#RequestMapping(value = "/file/upload", method = { RequestMethod.GET, RequestMethod.POST })
public String fileUpload(#RequestParam("file") MultipartFile file) { }
RestTemplate rest = new RestTemplate();
ResponseEntity<youclass> response= rest.exhange(url(your url to post or get), data(data u r sending to server), yourclass.class);
response.getBody() //response back from the server
Related
I am currently using Spring WebFlux to try build an async end-point, which fetches a PDF from a third-party end-point via Web Client before returning the PDF back to our API consumer. However, I am struggling with returning a Mono<ResponseEntity> with content type application/pdf due to the below exception:
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class reactor.core.publisher.MonoMapFuseable] with preset Content-Type 'application/pdf']
Here is controller implementation. My question is:
Is my implementation in the right direction, or would I need to create some sort of converter?
Does Mono<ResponseEntity> even support returning a PDF as a response body?
#RequestMapping(value="/get-pdf", method = RequestMethod.GET)
public Mono<ResponseEntity> getPDFAsync() {
String url = "http://some-end-point";
WebClient client = WebClient.create(url);
return client.get()
.accept(MediaType.APPLICATION_PDF)
.exchangeToMono(response ->
Mono.just(ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF)
.body(response.bodyToMono(ByteArrayResource.class)
.map(byteArrayResource -> byteArrayResource.getByteArray())
)));
}
To download a file reactively, you could supply the file as a Flux<DataBuffer>, where DataBuffer is org.springframework.core.io.buffer.DataBuffer, like this:
// some shared buffer factory.
private final DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
#RequestMapping(value = "/download",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_PDF_VALUE}
)
public Mono<ResponseEntity<Flux<DataBuffer>>> downloadDocument(
...
) {
return Mono.fromCallable(() -> {
return ResponseEntity.ok(
DataBufferUtils.read(
new File("somepdf.pdf").toPath(),
dataBufferFactory,
8096
))
});
}
Or more specifically, since you seem to be using the WebFlux WebClient, you can forward the response body flux directly to your own response, without having to buffer the complete response first:
#RequestMapping(value = "/download",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_PDF_VALUE}
)
public Mono<ResponseEntity<Flux<DataBuffer>>> downloadDocument(
...
) {
String url = "http://some-end-point";
WebClient client = WebClient.create(url);
return client.get()
.accept(MediaType.APPLICATION_PDF)
.exchange()
.map(response -> response.bodyToFlux(DataBuffer.class))
.map(ResponseEntity::ok);
}
Hint: I hope you are reusing the WebClient instance and not instantiating a new one on each request.
I have found the answer! In short, returning Mono<byte[]>, and add produces = {MediaType.APPLICATION_PDF_VALUE} to #RequestMapping works. See example below.
#RequestMapping(value="/get-pdf", produces = {MediaType.APPLICATION_PDF_VALUE}, method = RequestMethod.GET)
public Mono<byte[]> getPdf() {
String url = "some-end-point";
WebClient client = WebClient.create(url);
return client.get()
.accept(MediaType.APPLICATION_PDF)
.exchangeToMono(response -> response
.bodyToMono(ByteArrayResource.class))
.map(byteArrayResource -> byteArrayResource.getByteArray());
}
I have a Spring MVC Controller and a PUT mapping that consumes JSON. I receive the JSON and everything just fine, the problem is whenever I fire off the JSON the mapper wants to redirect to the URL, giving me error 500 because the server can't find any template for the URL. How can I stop Spring MVC from trying to redirect to the URL and just receive the JSON?
My relevant Controller code :
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public void removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
}
You can try to return ResponseEntity<Void>
#RequestMapping(value = "admin/users/VMs", method = RequestMethod.PUT, consumes = "application/json")
public #ResponseBody ResponseEntity<Void> removeVM(#RequestBody ManageVMRequest packet, Authentication authentication) {
System.out.println(packet.getVm());
System.out.println(packet.getUser_id());
return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
}
How can we provide document download using camel API, I need to provide an api using camel rest to response the file as download and I have the logic to create the pdf using apache fop, but i need to get some information how to respond the file as rest response using camel rest.
#RestController
public class MyController {
#Autowired
ICityService cityService;
#RequestMapping(
value = "/pdfreport",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_PDF_VALUE
)
public ResponseEntity<InputStreamResource> citiesReport() throws IOException {
List<City> cities = (List<City>) cityService.findAll();
ByteArrayInputStream bis = GeneratePdfReport.citiesReport(cities);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "inline;
filename = citiesreport.pdf");
return ResponseEntity
.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_PDF)
.body(new InputStreamResource(bis));
}
}
I am trying to use feign.HeaderMap annotation to pass a map of HTTP headers in the rest request but these are appearing in the body.
Code below:
#FeignClient(name = "accounts", url = "localhost:8080")
public interface AccountClient {
#RequestMapping(method = RequestMethod.GET, value = "/rest/accounts/get", produces = MediaType.APPLICATION_JSON_VALUE)
Account findOne(#RequestParam("id") String id, #HeaderMap Map headers);
}
You are mixing annotations. When using spring-cloud-netflix you will need to use the Spring annotation #RequestHeader instead.
#RequestMapping(method = RequestMethod.GET,
value = "/rest/accounts/get",
produces = MediaType.APPLICATION_JSON_VALUE)
Account findOne(#RequestParam("id") String id, #RequestHeader Map headers);
In Feign by default, all parameters not annotated will be serialized in the Body.
It will call another REST API with a GET request.
#RequestMapping(value = "xxxx/{id}", method = RequestMethod.GET)
public #ResponseBody GetObjet GET( #PathVariable("id") String id,
#RequestHeader(value="X-Auth-Token") String Token) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("X-Auth-Token", Token);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<GetObjet> response = restTemplate.exchange(url, HttpMethod.GET, entity, GetObjet.class);
return response.getBody();
}
Always 400 Error. It means that bad request or some errors in the request body. But this is GET so the resquest bodys is always empty. So this way to add header may be not right. Any ideas?
You can obtain the headers including the notation #RequestHeader in your method
public void displayHeaderInfo(#RequestHeader("Accept-Encoding") String encoding,
#RequestHeader("Keep-Alive") long keepAlive) {
}
o
You can read more about the request here
And the other way to abtain the URL is:
#RequestMapping(value = "/restURL")
public String serveRest(#RequestBody String body, #RequestHeader HttpHeaders headers){
//Use headers to get the information about all the request headers
long contentLength = headers.getContentLength();
...
StreamSource source = new StreamSource(new StringReader(body));
YourObject obj = (YourObject) jaxb2Mashaller.unmarshal(source);
...
}
Try using:
RestTemplate.getForEntity(url, GetObject.class);
You have some methods to request data from a rest API, such as getForEntity and getForObject, use the one you needed.