Image
I want to write a client code to consume an API. The API is expecting a text file. When I select the binary file option in the postman tool and select any text file from my local it worked. how to implement this in spring ?. I have tried MULTIPART_FORM_DATA but no luck.
If You mean file
#RestController
public class FileContentController {
#RequestMapping(value="/up", method = RequestMethod.POST)
public ResponseEntity<?> upload(#RequestParam("file") MultipartFile file)
throws IOException {
String contentType=file.getContentType());
InputStream i=file.getInputStream();
return new ResponseEntity<>(HttpStatus.OK);
}
return null;
}
also spring boot has multi part confs, you should enable it and set size and tempdir
,In Earlier version spring boot need to add:
spring.servlet.multipart.max-file-size=128KB
spring.servlet.multipart.max-request-size=128KB
spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}
However in your client code you should not set content-type application/json in your header post request
simple fetch should be such
const input = document.getElementById('uploadInput');
const data = new FormData();
data.append('file', input.files[0]);
var resp = await fetch('upload/', {
method: 'POST',
body: data
});
if (!resp.ok) {
throw new Error(`HTTP error! status: ${resp.status}`);
}
if (resp.ok) {
await this.images();
}
Related
I have Jersey endpoint that is attempting to create a CSV file and return it via GET; however, all these attempts end up with the same result - the ok status (200) is returned but no file.
#GET
#Path("/research")
#Produces(MediaType.TEXT_PLAIN)
public Response dumpAllResearchAndSupportData() {
QuickDumpBuilderService dumpBuilderService = getQuickDumpService();
List<DevelopmentProposal> researchOtherProposals = dumpBuilderService.getAllResearchRecords();
String csvLocation = dumpBuilderService.buildCSV(researchOtherProposals);
File file = new File(csvLocation);
String filename = "reserach_" + UUID.randomUUID().toString() + ".csv";
return Response.ok(file, MediaType.TEXT_PLAIN).header("Content-Disposition", "attachment; filename=" + filename).build();
}
My CSV file is properly created, but it fails to be returned along with the response.
Notice above, I'm writing the CSV to a temporary location in my tomcat folder and then passing the path to that file back and then attempting to read that from the location here.
Another attempt with the same result where instead of writing the CSV to temp location, I'm just trying to write the ByteArrayOutputStream to the response object.
#GET
#Path("/research")
#Produces(MediaType.APPLICATION_JSON)
public Response dumpAllResearchAndSupportData() {
QuickDumpBuilderService dumpBuilderService = getQuickDumpService();
// Step 1. Retrieve all research and other proposals
List<DevelopmentProposal> researchOtherProposals = dumpBuilderService.getAllResearchRecords();
// Step 2. Create CSV File
ByteArrayOutputStream csvBaos = dumpBuilderService.buildCSV(researchOtherProposals);
// Step 3. Create spreadsheet
ByteArrayOutputStream excelBaos = dumpBuilderService.createExcelSpreadsheet(csvBaos, servlet);
// Step 4. Return spreadsheet
Response.ResponseBuilder response = Response.ok(excelBaos);
return response.build();
Another attempt where I added this "writer" into the response. This attempt generated an error that a "MessageBodyWriter for the ByteArrayStream was not found." That prompted the attempt below.
#GET
#Path("/research")
#Produces(MediaType.TEXT_PLAIN)
public Response dumpAllResearchAndSupportData() {
....
// Step 4. Return spreadsheet
return Response.ok(getOut(csvBaos.toByteArray())).build();
}
private StreamingOutput getOut(final byte[] csvBytes) {
return new StreamingOutput() {
#Override
public void write(OutputStream out) throws IOException, WebApplicationException {
out.write(csvBytes);
out.flush();
}
};
}
I've looked at the following similar answers, and I've attempted all of them with no success.
Not sure what I'm doing wrong - I suspect that it's something to do with how I setup my endpoint and defer to the Java REST API experts here.
File download/save from a Jersey rest api call using ANGULARJS . file is attached with response as "Content-Disposition"
Download CSV file via Rest
jersey - StreamingOutput as Response entity
Thanks for your help.
I want to send a json to my REST API. i tried it with Postman and it works fine. Now i want to sent Data from my frontend. I dont know where i need to add the header and how i do it. Im using Springboot for my BackEnd and Vue for my FrontEnd.
My Controller:
#RestController
#RequestMapping("/api/auth")
public class FileController {
FileService fileService;
public FileController(FileService fileService) {
this.fileService = fileService;
}
#RequestMapping(
value = "/data",
method = RequestMethod.POST,
consumes = "application/json")
public void process(#RequestBody String payload) throws Exception{
System.out.println(payload);
try {
FileWriter writer = new FileWriter(...);
writer.write(payload);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
My main.js, which shall send the data:
const toSend ={
"name": "test",
"test1":"test2"
};
const jsonString = JSON.stringify(toSend);
const xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8090/api/auth/data");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(jsonString);
console.log(jsonString)
You need to enable cors for this controller.
There is an annotaion for that matter.
Check out this guide
https://spring.io/guides/gs/rest-service-cors/
Are you sure that sending by xhr is best solution? why don't you use fetch?
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
Yours vue app and spring boot apps runs on different ports and browser sees it separate websites that why it blocks because of cors. Other solution that adding cors headers, can be proxy on js side.
I have my endpoint in spring-boot API for uploading images. It's working fine with the postman, but if I want to send a request from my angular app I'm getting code 400 "Required request part 'file' is not present".
I think the problem is in my angular code.
My endpoint
#PostMapping(value = "/private/image/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public BasicImgurResponse uploadProfilePicture(#RequestParam(name = "file") MultipartFile file){
try {
return service.uploadProfilePicture(file);
} catch (IOException ex) {
Logger.getLogger(ImgurController.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
My angular service method
uploadAvatar(data: any){
let file = new FormData();
file.append('file',data);
return this.http.post<any>(environment.api_endpoint+'/private/image/avatar',file);
}
May be data object is empty? Make sure that data object contains a input file.
Without Angular, the command will be as below:
formData.append('file', $('input[type=file]')[0].files[0]);
I have a Spring based endpoint:
#PostMapping("/new")
public ResponseEntity house(#RequestBody Map<String ,Object> data) {
data.values().forEach(System.out::println);
return ResponseHub.defaultFound("");
}
I simply want to send a file along with some data. I'm using Ionic with Angular, so in angular I have:
let map = new TSMap();
map.set('field1', 'wan');
map.set('field2', 'two');
this.files = event.target.files;
map.set('files', this.files);
let data = map.toJSON();
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
let url = "http://localhost:8080/api/data";
this.http.post<HttpResponse>(url, data, httpOptions).pipe().toPromise().then(response=>{
console.log(response);
});
Sadly the output I get on my backend is just
wan
two
{0={}}
I know it's because I have Content-Type set to application/json in the http request I have on Angular. I've looked here and there, I've found a solution but allows uploading a single file and I won't be able to add any other data along with it. What would be the best solution?
Edit:
The html that calls the function that contains the Angular code:
<ion-item>
<ion-label id="profile_image" stacked>Select File</ion-label>
<ion-input type="file" accept=".png, .jpg" multiple (change)="selectFile($event)">
Select Image
</ion-input>
</ion-item>
This is where it gets the files from.
Suggested Solution:
I tried using FormData
selectFile(event) {
let formData = new FormData();
let map = new TSMap();
map.set('field1', 'wan');
map.set('field2', 'two');
let data = map.toJSON();
formData.append('data', JSON.stringify(data));
this.files = event.target.files;
formData.append('files', this.files);
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'multipart/form-data'
})
};
let url = "http://localhost:8080/api/data";
this.http.post<HttpResponse>(url, formData, httpOptions).pipe().toPromise().then(response=>{
console.log(response);
});
}
Backend:
#PostMapping("/data")
public ResponseEntity house(#RequestPart(name = "data") Map<String, Object> data,
#RequestPart(name = "files") MultipartFile[] files) throws IOException {
data.values().forEach(System.out::println);
for (MultipartFile file: files)
System.out.println(file.getInputStream().available());
return ResponseHub.defaultFound("");
}
Now it just gives me this error:
org.apache.tomcat.util.http.fileupload.FileUploadException: the
request was rejected because no multipart boundary was found
I have some xml files stored as strings in my database and scala+spring based backend with this controller:
#RequestMapping(value = Array("/download"), method = Array(RequestMethod.GET))
def downloadFile(#RequestParam filename: String, //some more params
response: HttpServletResponse) = {
val fileContent = // some logic here, returns file content as String
response.setContentType("application/xml")
response.setHeader("Content-Disposition", s"attachment;filename=$filename")
response.setStatus(HttpServletResponse.SC_OK)
response.getOutputStream.write(fileContent.getBytes)
response.flushBuffer()
}
Also i have this script:
$.ajax({
type: "GET",
url: url,
data: {
filename: filename //and some more params
}
})
Then i send HTTP request to server, get right HTTP response and then nothing happens. All info i have from browser logs is that response has file content in body and headers, but download never starts.
What am i doing wrong?
I saw these SO Q&A but they didnt help me at all:
download file using an ajax request
Downloading a file from spring controllers
UPD1:
Also tried this one, with no result.
This is how I made a file to download from a server.
output = (byte[]) processedDocumentObject;
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
responseHeaders.setContentDispositionFormData("attachment", "file.xml");
HttpEntity<byte[]> fileEntity = new HttpEntity<byte[]>(output,responseHeaders);
return fileEntity;
However this is in java and HttpHeaders is org.springframework.http.HttpHeaders and HttpEntity is org.springframework.http.HttpEntity<byte[]>
Also, you need to convert your string into byte array initially.