I have a interface in Java:
#RequestMapping(value = "/api/getPdf", method = RequestMethod.POST, headers = {"content-type=application/json"}
#ResponseBody public ResponseEntity<byte[]> getPdf(#RequestBody final DatosPdf datosPdf);
Implementation:
public ResponseEntity<byte[]> getPdf(#RequestBody final DatosPdf datosPdf) {
ByteArrayOutputStream archivo = new ByteArrayOutputStream();
Document documento = new Document();
PdfWriter.getInstance(documento, archivo);
documento.open();
documento.add(new Paragraph("Hello world"));
documento.close();
archivo.close();
String filename = "hello.pdf";
byte[] documentContent = archivo.toByteArray();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
headers.setContentDispositionFormData(filename, filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(documentContent, headers, HttpStatus.OK);
return response;
}
Function Javascript
HttpSrv.post('api/getPdf', datosPdf).then(function(pdf) {
//CODE TO OPEN PDF FILE
}, function(errorResponse){
});
In the FRONT I receive the byte[]
The Java implementation is correct?
How I can open the pdf in the browser?
Thanks!!
Related
The code below works when the frontend and backen are appart , not a jar file. Am I missing something?
#RequestMapping(value = "/getPdf/{userType}/{userRoll}/{trainingFileName}", method = RequestMethod.GET)
public ResponseEntity<InputStreamResource> getPdf(#PathVariable("userType") String userType,
#PathVariable("userRoll") String userRoll,
#PathVariable("trainingFileName") String trainingFileName) throws FileNotFoundException {
String fileName =trainingFileName + ".pdf";
String filePath = "TrainingDocuments\\SuperUser\\2\\PartnerInformation\\PartnerInformation.pdf";
//TrainingDocuments\SuperUser\2\PartnerInformation\PartnerInformation.pdf
File file = new File(filePath);
HttpHeaders headers = new HttpHeaders();
headers.add("content-disposition", "inline;filename=" +fileName);
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}
following is my Hosting Entity
#Entity
#Table(name = "Hosting")
public class Hosting {
#Id
private String uid;
// ********* for files ********
#Transient
private MultipartFile aadharFile;
private String aadharFileName;
private String aadharFileType;
#Lob
private byte[] aadharFileData;
}
following is my backend service
#GetMapping("/hostings/downloadIdProof/{uid}")
public ResponseEntity<byte[]> downloadIdProof (#PathVariable String uid) {
Hosting hosting = service.findById(uid).get();
HttpHeaders header = new HttpHeaders();
header.setContentType(MediaType.valueOf(hosting.getAadharFileType()));
header.setContentLength(hosting.getAadharFileData().length);
header.set("Content-Disposition", "attachment; filename=" + hosting.getAadharFileName());
return new ResponseEntity<>(hosting.getAadharFileData(), header, HttpStatus.OK);
}
and following is my react code
const downloadFile = (file) => {
hostingApi.get(`/hostings/downloadIdProof/${user.uid}`)
.then(response=>{
console.log(response)
var filename = response.headers["content-disposition"].split("filename=")[1];
let url= window.URL.createObjectURL(new Blob([response.data], {'type': `${response.headers["content-type"]}`}));
let a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
})
.catch(err=>{
console.log(err);
})
}
here file is downloaded but it is corrupted "It appears that we dont support this file foramat"
additional this is the formate of "response.data"
���� JFIF
I am trying from a .net client to download a file via a .net server (file is located on server machine ) using the StreamContent.However when launching the request i am getting the exception:
Exception
Stream does not support reading.
Client
class Program {
static async Task Main(string[] args) {
HttpClient client = new HttpClient();
using (FileStream stream = new FileStream("txt.path", FileMode.OpenOrCreate, FileAccess.Write)) {
var content = new StreamContent(stream);
var response = await client.PostAsync("http://localhost:5300/get", content);
}
}
}
Server
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
string fname = "dld.txt";
app.Run(async (context) => {
if (!(context.Request.Path == "get")) {
return;
}
File.WriteAllText(fname, "data is:" + DateTime.Now.ToString());
FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Read);
using (Stream stream = context.Response.Body) {
await fs.CopyToAsync(stream);
}
});
}
Hi you can use like this:
HttpContent stringContent = new StringContent(paramString); //if you want to use string
HttpContent fileStreamContent = new StreamContent(paramFileStream); //if you want to use file stream
HttpContent bytesContent = new ByteArrayContent(paramFileBytes);// if you want to use aray of bytes
using (var client = new HttpClient())
{
using (var formData = new MultipartFormDataContent())
{
formData.Add(stringContent, "param", "param");
formData.Add(fileStreamContent, "file", "file");
formData.Add(bytesContent, "file", "file");
var response = await client.PostAsync("some URL", formData);
if (!response.IsSuccessStatusCode)
{
return null;
}
return await response.Content.ReadAsStreamAsync();
}
}
I was having trouble getting the file because i wanted to use the Request.Body stream as a sink.I wanted the server to write the data on this stream (i thought the Request stream can be used both ways).
I have solved it by using the Response stream instead:
Client
static async Task Main(string[] args) {
HttpClient client = new HttpClient();
using (FileStream stream = new FileStream("data.txt", FileMode.OpenOrCreate, FileAccess.Write)) {
var content = new StringContent("not important");
var response = await client.PostAsync("http://localhost:5300/get",content);
await response.Content.CopyToAsync(stream);
}
}
I have images on machine of server. I want to retrieve image and display it in UI using angularjs.
I convert image to byte array in RestController. In angularjs, I send a request to get byte array then display byte array as an image in html. But image do not show on web page. Below is my code:
#RequestMapping(value = "/images", method = RequestMethod.GET)
public ResponseEntity<byte[]> getProductImage(String fileName) {
byte[] result = null;
File serverFile;
try {
serverFile = productService.getProductImage(fileName);
BufferedImage bufferedImage = ImageIO.read(serverFile);
// get DataBufferBytes from Raster
WritableRaster raster = bufferedImage.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
result = (data.getData());
} catch (IOException e) {
e.printStackTrace();
}
String mimeType = URLConnection.guessContentTypeFromName(fileName);
HttpHeaders headers = null;
if (mimeType != null) {
headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
}
return new ResponseEntity<>(Base64.getEncoder().encode(result), headers, HttpStatus.OK);
}
angularjs
vm.getByte = function(fileName){
$http({
method: 'GET',
url: '/api/images',
params: {
fileName: fileName
}
}).success(function(success){
vm.imgFile = success;
});
};
html code
<div class="form-group">
<label>Image</label>
<div class="form-group has-avatar" ng-if="vm.Product.productImg">
<img ng-src="data:image/JPEG;base64,{{vm.imgFile}}" style="width: 200px;height: 130px;" />
current result:
result
You should fix code in java follow:
#RequestMapping(value = "/images", method = RequestMethod.GET)
public ResponseEntity<byte[]> getProductImage(String fileName) {
byte[] result = null;
File serverFile;
try {
serverFile = productService.getProductImage(fileName);
FileInputStream fi = new FileInputStream(serverFile);
result = Base64.getEncoder().encode(IOUtils.toByteArray(fi));
} catch (IOException e) {
e.printStackTrace();
}
String mimeType = URLConnection.guessContentTypeFromName(fileName);
HttpHeaders headers = null;
if (mimeType != null) {
headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(mimeType));
}
return new ResponseEntity<>(result, headers, HttpStatus.OK);
}
At client I have:
for (var i = 0; i < $files.length; i++) {
var file = $files[i];
var data = {f_name: 'test1', s_name: 'test2'};
var fd = new FormData();
fd.append('data', angular.toJson(data));
fd.append("file", file);
$http({
method: 'POST',
url: 'EmployeeService/employee/upload',
headers: {'Content-Type': undefined},
data: fd,
transformRequest: angular.identity
})
.success(function(data, status) {
alert("success");
});
}
And on server (Spring):
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") Object data) throws Exception {
System.out.println("data = " + data);
return "OK!";
}
But data is String: "{"f_name":"test1","s_name":"test2"}". A have DTO-class:
public class EmployeeDTO(){
private String f_name;
private String s_name;
//setters and getters
}
And on server I want to get:
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") EmployeeDTO employeeDTO) throws Exception {
//etc.
}
How to send data from client (file and data) and on server get file and EmployeeDTO object?
while you can use annotation #RequestBody to get Object from json string.
for example:
#ResponseBody
#RequestMapping(value = "/test", method = RequestMethod.POST)
public String test(#RequestBody EmployeeDTO employeeDTO){
//TODO do something;
return "success";
}
or you can receive string and then use ObjectMapper to convert string to object
for example:
EmployeeDTO employeeDTO = new ObjectMapper().readValue("here is json string", EmployeeDTO.class);
You could register a Converter<String, EmployeeDTO> that would use Json ObjectMapper and you could write you controller method as you want (I assume you use Jackson2)
If you need that in only this method, it may be simpler to do it explicitely :
#Autowired
private MappingJackson2HttpMessageConverter jsonConverter;
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") String data) throws Exception {
EmployeeDTO employeeDTO = jsonConverter.getObjectMapper().readValue(data,
EmployeeDTO.class);
return "OK!";
}
Alternatively, you could put the object directly in the FormData (angularJS side) and get it with #ModelAttribute spring side :
var fd = new FormData();
fd.append("file", file);
fd.append("f_name", 'test1');
fd.append("s_name", 'test2'};
and
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#ModelAttribute EmployeeDTO employeeDTO) throws Exception {