How to test a dropbox upload in Java with Spring Boot? - java

I have the following code snippet:
#RestController
#RequestMapping("/dropbox")
public class DropboxController {
private static final Logger logger = LoggerFactory.getLogger(DropboxController.class);
#Autowired
DropboxService dropboxService;
#Autowired
DbxClientV2 dropboxClient;
#PostMapping("/upload")
public String handleFileUplad(#RequestParam("file") MultipartFile file, #RequestParam("filePath") String filePath) throws Exception {
dropboxService.uploadFile(file, filePath);
return "You successfully uploaded " + filePath + "!!";
}
Now I want to test whether the upload works. How can I do this? How would be the syntax when I try it with curl?

Source: https://www.mkyong.com/spring/curl-post-request-examples/
To POST with a file, add this -F file=#"path/to/data.txt"
$ curl -F file=#"path/to/data.txt" http://localhost:8080/dropbox/upload

Also as an alternative you can use Postman
Add form-data as body with 2 parameters and select the type as file

Related

upload to local WebDav - spring boot

I have problem with upload file to local WebDav. So far i have:
public interface IStorageService {
URI SaveFile(String filename, InputStream inputStream);
}
#Component
public class LocalStorageService implements IStorageService {
#Value( "C:\temp" )
private String filestorePath;
public URI SaveFile(String filename, InputStream inputStream) {
var rootLocation = Paths.get(filestorePath);
var filePath = rootLocation.resolve(filename);
try {
Files.copy(inputStream, filePath);
} catch (IOException e) {
throw new RuntimeException("Failure save file to " + filename + " in " + filestorePath + "." + e.getMessage(), e);
}
return filePath.toUri();
}
}
and controller
private final DocumentService documentService;
public DocumentController(DocumentService documentService) {
this.documentService = documentService;
}
#RequestMapping(method = RequestMethod.POST)
public DocumentModel handleFileUpload(#RequestParam("file") MultipartFile file) throws IOException {
return documentService.handleFileUpload(file.getOriginalFilename(), file.getInputStream());
}
And it is works correctly, the file is uploaded to C:/temp...
Now I would like to do the same but upload file to local WebDav. When i change in #Value "C:\temp to "http://localhost" (this is ma webdav location) i have:
invalidpathexception: illegal char <:> at index 4: http://localhost
or when I declare http//localhost without <:>
nosuchfileexception: http\localhost
How can I write my code to upload file directly to WebDav.
Parameters of SaveFile method cannot be changed, I need do it with Name as String and InputStream.
I tried with Sardine but to no avail. Could someone help me, give any tips or maybe suggestion of code ?
Greetings !
You can get the path where your web app/ war/ servlet / controllers are deployed :
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");
For a Spring project, in controller
'#Autowired
'ServletContext context;
And in controller method :
'String uploadPath = context.getRealPath("") + File.separator + UPLOAD_DIRECTORY;
And the real file name, but what if a user uploads same file twice or 2 users upload file with same name?
Better to put in sub directory with user id/ user name and maybe date time or some other identifier like TXN id + some fixed text like
' String fileName = context.getRealPath("") + File.separator + userId + readlName + "xyz."
extnFromMimeType;
And store the path in data base for this transaction/ user as per your busibess use case.
if mime type is image/PMG then extnFromMimeType will be "png"; if jpeg or jpg then "jpg"
See
File path to resource in our war/WEB-INF folder?
how to get getServletContext() in spring mvc Controller
In Spring MVC, how can I set the mime type header when using #ResponseBody
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
If can be many images per user/ transaction can also use createTemp File to get a unique file name
using a UUID also possible ... https://stackoverflow.com/a/1293712/1643558 or a large random number

SpringBoot + Postman #RequestMapping value = "getImage/{imageName:.+}"

I an creating an endpoint with spring boot...i can upload image to folder and save it via postman everythink works good.
i have a problem with get method when i am adding the value #RequestMapping value = "getImage/{imageName:.+}" in postman i add http://localhost:8080/api/images/getImage/{burger+png}
is that corect ???
#RequestMapping(value = "api/images")
public class ImageController {
#Autowired
public ImageService imageService;
#PostMapping(value ="upload")
public ResponseEntity uploadImage(#RequestParam MultipartFile file){
return this.imageService.uploadToLocalFileSystem(file);
}
#GetMapping(
value = "getImage/{imageName:.+}",
produces = {MediaType.IMAGE_JPEG_VALUE,MediaType.IMAGE_GIF_VALUE,MediaType.IMAGE_PNG_VALUE}
)
public #ResponseBody byte[] getImageWithMediaType(#PathVariable(name = "imageName") String fileName) throws IOException {
return this.imageService.getImageWithMediaType(fileName);
}
}
what should be the correct request url ???
It seems like it's reaching the backend fine, but failing to find path. Usually API endpoints end with parameters with a slug or query param. You can try either of the following to see if it works:
http://localhost:8080/api/images/getImage/burger.png
http://localhost:8080/api/images/getImage?imageName=burger.png
Keep in mind, you want to make sure that file exists at the path it's mentioning at the very top of the trace in the JSON response. This may depend on how you uploaded the file and with what name.

Java-spingboot how to save text document via REST-API?

I am a beginner programmer, help with the implementation of uploading a text file via rest-api java.
I have already implemented the simplest action - unload a file from the server, here is my code:
#GetMapping(value = "/file/{filename:.+}")
public ResponseEntity<Resource> unloadFile(#PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFilename() + "\"").body(file);
}
I can test the file unload by simply following the link!
I cannot test the upload. I find it difficult to write tests. Please tell me if I got a working code and maybe there is a better way to upload. My code upload:
#PostMapping(value = "/file")
public ResponseEntity<MultipartFile> uploadFile(MultipartFile file) {
storageService.store(file);
return ResponseEntity.ok().body(file);
}
Thank you so much!
To upload the file/files using spring boot application we use same method that we had for servlet containers. In your controller
#PostMapping("/uploadFile")
public ResponseEntity<Object> uploadFile(#RequestParam("file") MultipartFile file) {
String fileName = yourStorageService.storeFile(file);
String = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
//You can even generate download links.
return new ResponseEntity<Object>(HttpStatus.Ok, "Uploaded", fileDownloadUri);
}
To download the files:
#GetMapping("/downloadFile/{fileName}")
public ResponseEntity<Resource> downloadFile(#PathVariable String fileName, HttpServletRequest request) {
// Load file as Resource from DB or local
Resource resource = fileStorageService.loadFileAsResource(fileName);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
For #PostMapping(value = "/file") endpoint , its best to return a success/error status instead of returning the file,if file is larger ..it takes time to return back.
Better to return success state. 200 ok.

Can we use multipart and #RequestBody together in spring?

I want to create a API which can have parameter as multipart file and JSON object (#RequestBody). Please find following snippet while calling this API. I am getting HTTP 415 Unsupported Media Type error. If I remove #RequestBody LabPatientInfo reportData then it works fine.
#RequestMapping(value={"/lab/saveReport"}, method={RequestMethod.POST},
consumes={"multipart/form-data"}, headers={"Accept=application/json"})
#ResponseBody
public ResponseEntity<String>
saveReport(#RequestParam(value="reportFile") MultipartFile reportFile,
#RequestBody LabPatientInfo reportData) throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8");
logger.info("in Lab Save Report");
logger.info("Report Data {} ", reportData);
//logger.info("Request BODY {} ", request.getAttribute("data"));
return new ResponseEntity<String>(HttpStatus.OK);
}
following is LabPatientInfo class.
#RooJson(deepSerialize = true)
#RooToString
public class LabPatientInfo {
private String firstName;
private String phoneNumber;
private String DateOfBirth;
private Integer age;
private String gender;
private String refferedBy;
private String reportfile;
private String reportType;
private String reportDate;
private String purpose;
private String followUpDate;
private List<ReportDataInfo> analytes;
while hitting API I am passing following JSON object with uploaded file..
{
"firstName":"abc",
"phoneNumber":"898989",
"DateOfBirth":"asas",
"age":"asas",
"gender":"asas",
"refferedBy":"asas",
"reportfile":"asas",
"reportType":"asas",
"reportDate":"asas",
"purpose":"asas",
"followUpDate":"asas",
"analytes":null
}
You can use #RequestPart like below. This will support both json object and multipart file.
#ResponseBody
public ResponseEntity<String>
saveReport(#RequestPart (value="reportFile") MultipartFile reportFile,
#RequestPart LabPatientInfo reportData) throws IOException {
In order to test it using curl you can create one file for your json part (reportData). Say for example you create "mydata.json" file and paste your json payload in it. And say your reportFile is "report.txt". Now you can send request using curl like below.
curl -v -H "Content-Type:multipart/form-data" -F "reportData=#mydata.json;type=application/json" -F "reportFile=#report.txt;type=text/plain" http://localhost:8080/MyApp/lab/saveReport
An example of a post method which receives a json object and a generic file:
public ResponseEntity<Resource> postGenerateReport(#RequestPart GenerateReportDTO, generateReportDTO, #RequestPart MultipartFile jxhtmlReport)
For the PostMan setup (or curl or anyother REST test utility) you just have to add form-data request with 2 elements:
Key:generateReportDTO, Value: File with .json extension (and compatible content with the object)
Key:jxhtmlReport, Value: just any file.
Gl
When a parameter is annotated with #RequestPart the content of the part is passed through an HttpMessageConverter to resolve the method argument with the 'Content-Type' of the request part in mind. This is analogous to what #RequestBody does to resolve an argument based on the content of a regular request.
so, we can parse #Requestbody as #RequestPart as "abaghel" and reportData need to be a json file.
Spring Roo 2.0.0.M3 includes support for automatic scaffolding of a REST API.
For complete information, see the REST API in the reference manual.
Note the M3 version generate artifacts that could change in newer versions, so your project might not upgrade automatically if you open it with RC1 or above.
May the Force be with you.

Spring: refering the resources/static folder

I am developing a Rest API using Spring Boot and AngularJS in the client side, i am uploading files to /resources/static/upload with Spring using the RestController below and using them in the client side
#RestController
#CrossOrigin("*")
public class FilmController {
#Autowired
private FilmRepository filmRepository;
#RequestMapping(value = "/films", method = RequestMethod.POST)
public void saveFilm(#RequestParam("file") MultipartFile file) throws Exception {
File convFile = new File("src/main/resources/static/upload/"+file.getOriginalFilename());
convFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convFile);
Blob blob = new SerialBlob(file.getBytes());
fos.write(file.getBytes());
fos.close();
System.out.println(convFile.getName());
filmRepository.save(new Film(convFile.getName(), blob));
}
#RequestMapping(value = "/films", method = RequestMethod.GET)
public List<Film> getAllFilms() {
return filmRepository.findAll();
}
}
Here is how i accessed the uploaded image "image.jpg"
<img src="http://localhost:8080/upload/image.jpg" />
But, when i ran mvn package and i launch my application jar file, i can't access the uploaded image in the client side, i get 404 not found.
Can someone explain how Spring store and refer to static resources and how can i resolve this problem.
I'm using absolute path to the directory and this works in both cases: when it's runing with mvn spring-boot:run and when it's running as java -jar app.jar.
For example, you could try to save uploads to /opt/upload (make sure that it exists and user has permissions to write into it):
File convFile = new File("/opt/upload/"+file.getOriginalFilename());
Also you should configure Spring to serve uploads from this directory:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/upload/**")
.addResourceLocations("file:/opt/upload/");
}
}
More info about configuring resource handler: http://www.baeldung.com/spring-mvc-static-resources
First of all you cannot store in the folder structure you see in your IDE that is not how your code will be in a deployed package
File convFile = new File("src/main/resources/static/upload/"+file.getOriginalFilename());
store using relative path
File convFile = new File("/static/upload/"+file.getOriginalFilename());
and also add the resource location mapping in spring config for your image upload folder .
<mvc:resources mapping="/upload/**" location="/static/upload/" />

Categories

Resources