Return a file from Controller in Spring - spring
I am new to spring. I have a controller with a RequestMapping for several GET parameters. They return a String .
But one method needs to return a file in the "/res/" folder. How do I do that?
#RequestMapping(method = RequestMethod.GET,value = "/getfile")
public #ResponseBody
String getReviewedFile(#RequestParam("fileName") String fileName)
{
return //the File Content or better the file itself
}
Thanks
Thanks to #JAR.JAR.beans. Here is the link: Downloading a file from spring controllers
#RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
#ResponseBody
public FileSystemResource getFile(#PathVariable("file_name") String fileName) {
return new FileSystemResource(myService.getFileFor(fileName));
}
May be this will help
#RequestMapping(method = RequestMethod.GET,value = "/getfile")
public #ResponseBody
void getReviewedFile(HttpServletRequest request, HttpServletResponse response, #RequestParam("fileName") String fileName)
{
//do other stuff
byte[] file = //get your file from the location and convert it to bytes
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType("image/png"); //or whatever file type you want to send.
try {
response.getOutputStream().write(image);
} catch (IOException e) {
// Do something
}
}
Another way, though Jatin's answer is way cooler :
//Created inside the "scope" of #ComponentScan
#Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
#Value("${files.dir}")
private String filesDir;
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/files/**")
.addResourceLocations("file:" + filesDir);
}
}
Lifted from:
http://www.baeldung.com/spring-mvc-static-resources
https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources
This works like a charm for me:
#RequestMapping(value="/image/{imageId}", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImage(#PathVariable String imageId) {
RandomAccessFile f = null;
try {
f = new RandomAccessFile(configs.getImagePath(imageId), "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
f.close();
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(b, headers, HttpStatus.CREATED);
} catch (Exception e) {
return null;
}
}
If you are working on local Windows machine this could be useful for you:
#RequestMapping(value="/getImage", method = RequestMethod.GET)
#ResponseBody
public FileSystemResource getUserFile(HttpServletResponse response){
final File file = new File("D:\\image\\img1.jpg");
response.reset();
response.setContentType("image/jpeg");
return new FileSystemResource(file);
}
for testing your code you can use Postman "Use Send And Download not just send"
Another Approach to return byte:
#GetMapping("/getAppImg")
#ResponseBody
public byte[] getImage() throws IOException {
File serveFile = new File("image_path\\img.jpg");
return Files.readAllBytes(serveFile.toPath());
}
Related
Serving list of images in spring boot
I have created assets folder inside resources. I want to display list of image names in the assets folder. By clicking image name, it should open the particular image. I can access the images separately but how to display all the images as file explorer.
You might use ResourcePatternResolver: #Controller #RequestMapping("/assets") public class AssetController { #Autowired private ResourcePatternResolver resolver; #GetMapping("") #ResponseBody public String resources() throws IOException { final String root = resolver.getResource("classpath:/static/assets").getURI().toString(); final Resource[] resources = resolver .getResources("classpath:/static/assets/**/*.png"); final List<String> fileNames = Stream.of(resources) .filter(Resource::isFile) .map(r -> { try { return r.getURI().toString().replace(root, ""); } catch (final IOException e) { throw new IOError(e); } }) .collect(Collectors.toList()); final StringBuilder html = new StringBuilder(); html.append("<html>"); html.append("<ul>"); for (final String fileName : fileNames) { html.append("<li>"); html.append("" + fileName + ""); html.append("</li>"); } html.append("</ul>"); html.append("</html>"); return html.toString(); } }
Post Request return 404 for Spring Boot with Postman
I am trying to use postman to test one of the post requests I created for my spring boot application. My post requests through postman always return 404. I have created a same mapping route for a get request and with the postman, the get request works as expected. I have tested with aws cli and made sure that I have the correct access key and secret key for uploading files to S3. Code for my services #Service public class AmazonClient { private AmazonS3 s3client; #Value("${amazonProperties.endpointUrl}") private String endpointUrl; #Value("${amazonProperties.bucketName}") private String bucketName; #Value("${amazonProperties.accessKey}") private String accessKey; #Value("${amazonProperties.secretKey}") private String secretKey; #PostConstruct private void initializeAmazon() { AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey); this.s3client = AmazonS3ClientBuilder.standard().withRegion(Regions.US_EAST_2).withCredentials( new AWSStaticCredentialsProvider(credentials)).build(); } #Async public String uploadFile(MultipartFile multipartFile, boolean enablePublicReadAccess) { String fileUrl = ""; System.out.println("Reach"); try { File file = convertMultiPartToFile(multipartFile); String fileName = generateFileName(multipartFile); System.out.println("FileName: " + fileName); fileUrl = endpointUrl + "/" + bucketName + "/" + fileName; PutObjectRequest putObjectRequest = new PutObjectRequest(this.bucketName, fileName, file); if (enablePublicReadAccess) { putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead); } s3client.putObject(putObjectRequest); file.delete(); } catch (Exception e) { e.printStackTrace(); } return fileUrl; } private File convertMultiPartToFile(MultipartFile file) throws IOException { File convFile = new File(file.getOriginalFilename()); FileOutputStream fos = new FileOutputStream(convFile); fos.write(file.getBytes()); fos.close(); return convFile; } private String generateFileName(MultipartFile multiPart) { return new Date().getTime() + "-" + multiPart.getOriginalFilename().replace(" ", "_"); } public String deleteFileFromS3Bucket(String fileUrl) { String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1); s3client.deleteObject(new DeleteObjectRequest(bucketName, fileName)); return "Successfully deleted"; } } Code for my controller: #RestController #RequestMapping("/storage/files") public class BucketController { private AmazonClient amazonClient; #Autowired BucketController(AmazonClient amazonClient) { this.amazonClient = amazonClient; } #GetMapping public String getFile(){ return "Files"; } #PostMapping("/file") public String file() { return "Reach!"; } #PostMapping public String uploadFile(#RequestPart(value = "file") MultipartFile file) { System.out.println("Reach!!"); return this.amazonClient.uploadFile(file, true); } #DeleteMapping public String deleteFile(#RequestPart(value = "url") String fileUrl) { return this.amazonClient.deleteFileFromS3Bucket(fileUrl); } } My security config: #Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/css/**", "/js/**", "/fonts/**", "/index").permitAll() .antMatchers("/storage*").permitAll(); Through postman, I have selected a POST request and put http://localhost:8080/storage/files/file, in the body, I have entered a key "file" and set the value to a file type and chose a file from my local. Here is the response: { "timestamp": "2019-09-02T19:09:54.864+0000", "status": 404, "error": "Not Found", "message": "No message available", "path": "/storage/files/file" } Project Structure Postman Results
This is almost certainly your security config interfering. Have you tried: .antMatchers("/storage/**") instead?
File upload with in Spring MVC without adding any additional parameter in controller method
I am using spring boot 2. My new task is file uploading. I already did it. But I am asked to do it without adding a additional parameter to controller method like #RequestParam("files") MultipartFile files[]. I want to get this from request instead of adding this parameter. How can I solve this? I am adding my current code following. #RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST) public #ResponseBody String handleFileUpload( #RequestParam("files") MultipartFile files[]){ try { String filePath="c:/temp/kk/"; StringBuffer result=new StringBuffer(); byte[] bytes=null; result.append("Uploading of File(s) "); for (int i=0;i<files.length;i++) { if (!files[i].isEmpty()) { bytes = files[i].getBytes(); BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath+files[i].getOriginalFilename()))); stream.write(bytes); stream.close(); result.append(files[i].getOriginalFilename() + " Ok. ") ; } else result.append( files[i].getOriginalFilename() + " Failed. "); } return result.toString(); } catch (Exception e) { return "Error Occured while uploading files." + " => " + e.getMessage(); } }
You can get files from HttpRequest: #RequestMapping(value="/uploadMultipleFiles", method=RequestMethod.POST) public String handleFileUpload(HttpRequest request){ MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; Map<String, MultipartFile> yourFiles = multipartRequest.getFileMap(); return "All is Ok!"; }
My sample code. #RequestMapping(value = "/multiple/upload", method = RequestMethod.POST) public #ResponseBody String test(#RequestParam(value = "files[]") List<MultipartFile> files, HttpServletRequest req) { MultipartFileWriter writer = new MultipartFileWriter(); String folderPath = "/file/"; for (MultipartFile file : files) { writer.writeFile(file, folderPath, req); } return "success"; }
How to access CSV data set config in my Java Request Sampler
I have to read data from a csv file which contains 10000+ records. I want to use this data in JMeter to hit a web service. I had written my code with the hard coded value. But I want to make it dynamic. How can I access CSV data set config in my custom Java Request Sampler...? How can I access the variable i declared in the CSV data set config in my java request sampler..? Here is my full code : #Override public SampleResult runTest(JavaSamplerContext arg0) { SampleResult result = new SampleResult(); boolean success = true; byte arr[] = new byte[] {1,49,45,1,2,(byte)214,1,1,98,0,6,0,0,9,24,0,0,0,0,0,0,0,0,0,0,0,0,0,127,(byte)255,0,21,0,16,0,75,1,0,0,58,32,2,7,0,0,4,4,0,85,81,98,0,5,14,(byte)158,0,2,0,0,0,0,0,88,82,50,69,49,83,49,86,48,67,48,0,0,1,97,75,0,84,30,12,7,17,5,7,50,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,4,6,0,0,48,49,48,48,49,48,51,48,0,0,0,0,0,0,0,0,0,0,70,48,10,29,22,85,0,1,(byte)134,(byte)160,(byte)255,(byte)255,(byte)158,(byte)170,0,0,0,67,0,0,0,0,2,0,0,12,0,12,0,12,0,12,0,13,0,12,0,13,0,12,0,13,0,12,0,13,0,13,0,12,0,12,0,12,0,12,0,13,0,12,0,13,0,13,0,12,0,13,0,13,0,12,0,13,0,13,0,12,0,13,0,13,0,13,0,12,0,13,0,13,0,13,0,14,0,13,0,12,0,13,0,13,0,13,0,13,0,12,0,13,0,13,0,13,0,14,0,13,0,13,0,13,0,12,0,13,0,13,2,(byte)158,2,(byte)159,2,(byte)241,2,(byte)234,5,48,5,68,8,90,7,(byte)193,6,15,4,10,3,100,4,(byte)224,7,47,6,72,4,(byte)170,4,4,4,7,5,16,6,107,6,114,5,(byte)195,4,(byte)179,2,(byte)198,0,13,0,13,0,13,0,14,0,13,0,13,0,14,0,13,0,14,0,13,0,13,0,14,0,13,0,13,0,14,0,13,0,14,0,13,0,14,0,13,0,14,0,13,0,13,0,101,0,99,0,(byte)129,0,(byte)129,2,81,2,(byte)224,1,(byte)153,0,(byte)30,0,31,0,14,0,13,0,14,0,13,0,14,0,14,0,13,0,14,0,13,0,14,0,14,0,21,0,86,0,98,0,51,0,72,0,104,0,(byte)144,0,(byte)175,0,(byte)174,0,(byte)174,2,20,4,(byte)132,4,103,5,96,0,126,0,14,0,14,0,14,0,14,0,14,0,15,0,14,0,14,0,14,0,14,0,14,0,85,1,41,1,104,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,13,0,14,0,14,0,14,0,13,0,14,0,13,0,14,0,13,0,14,0,13,0,14,0,13,0,14,0,14,0,13,0,14,0,13,0,13,0,13,0,13,0,13,0,12,0,13,0,13,0,14,0,13,0,13,0,13,0,13,0,13,0,13,0,13,0,14,0,13,0,13,0,14,0,13,0,13,0,14,0,13,0,13,0,13,0,13,0,13,0,(byte)226,0,(byte)223,0,(byte)223,0,15,0,14,0,13,0,115,0,(byte) 223,(byte)162,40,38,85,115,101,114,78,97,109,101,61,101,82,101,103,38,85,115,101,114,80,97,115,115,119,111,114,100,61,97,98,99,49,50,51}; try { URL obj = new URL(POST_URL); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); result.sampleStart(); OutputStream os = con.getOutputStream(); os.write(arr); os.flush(); os.close(); result.sampleEnd(); int responseCode = con.getResponseCode(); System.out.println("POST Response Code :: " + responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { //success BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // print result System.out.println(response.toString().getBytes()); } else { System.out.println("POST request not worked"); } } catch(Exception E) { } // result.setSuccessful(success); return result; } #Override public Arguments getDefaultParameters() { Arguments dp=new Arguments(); return dp; } #Override public void setupTest(JavaSamplerContext context) {} #Override public void teardownTest(JavaSamplerContext context) { }
Normally you should be able to access JMeter Variables like: String myVar = JMeterContextService.getContext().getVariables().get("your_variable_name_here"); However if you don't want to have it hard-coded you might consider moving the configuration to Java Request Sampler GUI like: String valueFromCsv = ""; String defaultValue = "insert_jmeter_variable_here"; #Override public Arguments getDefaultParameters() { Arguments dp = new Arguments(); dp.addArgument("hexData", "insert_jmeter_variable_here"); return dp; } #Override public void setupTest(JavaSamplerContext context) { valueFromCsv = context.getParameter("hexData", defaultValue ); } This way you will be able to control the parameter value directly from JMeter GUI. References: JMeterContextService JavaDoc Java Request Sampler documentation Extending JMeter Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For!
A full java sampler solution with CSV data: courtesy - https://dzone.com/articles/implement-custom-jmeter-samplers Created a class public class VDCSampler extends AbstractJavaSamplerClient implements Serializable { private static final String ARG1_IDATE = "idate"; private String attrib1; #Override public Arguments getDefaultParameters() { Arguments defaultParameters = new Arguments(); defaultParameters.addArgument(ARG1_IDATE, attrib1); return defaultParameters; } #Override public void setupTest(JavaSamplerContext javaSamplerContext) { attrib1 = javaSamplerContext.getParameter(ARG1_IDATE, attrib1); } #Override public SampleResult runTest(JavaSamplerContext javaSamplerContext) { VDCFunctionalitySampling functionalityForSampling = new VDCFunctionalitySampling(); SampleResult sampleResult = new SampleResult(); sampleResult.sampleStart(); try { String message = functionalityForSampling.testFunction(attrib1); } }
Uploading Image/Photo in struts1
I would like to get Coding To Upload Image(.jpg)/Photo to Server Machine using Struts1.x and mySQL database I have the code for File Upload Instead. Let me know what tweaking is required here. TC Code for File Upload :---- public class FileUploadForm extends ActionForm{ private FormFile file; public FormFile getFile() { return file; } public void setFile(FormFile file) { this.file = file; } #Override public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if( getFile().getFileSize()== 0){ errors.add("common.file.err", new ActionMessage("error.common.file.required")); return errors; } //only allow textfile to upload if(!"text/plain".equals(getFile().getContentType())){ errors.add("common.file.err.ext", new ActionMessage("error.common.file.textfile.only")); return errors; } //file size cant larger than 10kb System.out.println(getFile().getFileSize()); if(getFile().getFileSize() > 10240){ //10kb errors.add("common.file.err.size", new ActionMessage("error.common.file.size.limit", 10240)); return errors; } return errors; } } Action Class:-- public class FileUploadAction extends Action{ #Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { FileUploadForm fileUploadForm = (FileUploadForm)form; FormFile file = fileUploadForm.getFile(); //Get the servers upload directory real path name String filePath = getServlet().getServletContext().getRealPath("/") +"upload"; //create the upload folder if not exists File folder = new File(filePath); if(!folder.exists()){ folder.mkdir(); } String fileName = file.getFileName(); if(!("").equals(fileName)){ System.out.println("Server path:" +filePath); File newFile = new File(filePath, fileName); if(!newFile.exists()){ FileOutputStream fos = new FileOutputStream(newFile); fos.write(file.getFileData()); fos.flush(); fos.close(); } request.setAttribute("uploadedFilePath",newFile.getAbsoluteFile()); request.setAttribute("uploadedFileName",newFile.getName()); } return mapping.findForward("success"); } } Thanks in Advance!