I have been learning spring and to get the things together I am making an e-commerce application. I have used rest api to connect client and server. Now i need to send images to the client. My images are already stored in src/resources folder. What i need to know is that how do i send those images through rest api. so that i can use it in my client
I am very noob at this. I tried google and all i can find is examples of image files uploading to the server. I can't find a example of sending file from server to client through rest api. i've been stuck in this for past three day
Here is my rest controller:
now i need to know what should i do next so that i can send images
#RestController
#RequestMapping("/api")
public class CategoriesRestController {
// autowire customer service
#Autowired
private CategoriesService service;
//add mapping for GET all customer
#GetMapping("/categories")
public List<Categories> getCategories() {
return service.getCategories();
}
// adding mapping for GET only one customer
#GetMapping("/categories/{categoryId}")
public Categories getCategory(#PathVariable int categoryId) {
Categories categories = service.getCategory(categoryId);
if(categories == null) {
throw new CustomerNotFoundException("Customer id not found- "+ categoryId);
}else {
return categories;
}
}
// adding mapping for POST/customer i.e. insert a customer
#PostMapping("/categories")
public Categories addCategories(#RequestBody Categories theCategories) { //#RequestBody will convert JSON to JAVA object
// just to make things clear... always set id to 0 when inserting new object
// so that it will be created instead of update
theCategories.setId(0);
service.saveCategories(theCategories);
return theCategories;
}
You might be thinking about the problem the wrong way. Instead of sending the image itself through the rest API, the HTML only needs the path to the image. You store the image in a directory, and you can pass the path to the image to your HTML. You could add a variable "imagePath" to Categories and the HTML could reference it in the tag
You can convert your images to base64:
byte[] fileContent = FileUtils.readFileToByteArray(new File(filePath));
String encodedString = Base64.getEncoder().encodeToString(fileContent);
and then send this property through your API. then in your client side you can use it like this:
<img src=json.encodedString />
Here json is an object which has been sent over API.
Before sending the encodedString you may appned at its beginning some things like below, to make it easier to display in front-end:
"data:image/png;base64,"
To display a base64 image in front-end you should use some thing like this:
<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
Read more:
https://www.baeldung.com/java-base64-image-string
How to display Base64 images in HTML?
Related
I am creating a microservice using spring boot where in i have a file handling.
My task is to write the QR code to image file and base64 encode to transfer over network.
Because I need to write to an image file and then read and then base64 encode it , I need to first create the image file and then write to it.
Creating a temperory folder and keep the file ?, create a folder in root directory and keep the file? or use the java.io.tmpdir ....
Note: I have no use of this file once I encode it. Also there are lot of user to whom we will be exposing this service as rest api.
I want to know what is the best way to do this.
If you are using the https://github.com/zxing/zxing library i.e.
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
Then something like the following will work.
#RestController
public class TestController {
#GetMapping(value = "/test")
public QrInfo getQrInfo() throws Exception {
String url = "https://news.bbc.co.uk";
int imageSize = 200;
BitMatrix matrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE,
imageSize, imageSize);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(matrix, "png", bos);
String image = Base64.getEncoder().encodeToString(bos.toByteArray()); // base64 encode
// return QrInfo
QrInfo qrInfo = new QrInfo();
qrInfo.setUrl(url);
qrInfo.setImage(image);
return qrInfo;
}
}
#Data // lombok for brevity
class QrInfo {
private String url;
private String image;
}
NOTE: This approach doesn't write any files but does it all in-memory using a ByteArrayOutputStream .
If you hit this endpoint you'll see the following: -
{
"url": "https://news.bbc.co.uk",
"image": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAQAAAACFI5MzAAABGUlEQVR42u2YSw7DIAxEzYpjcFM+N+UYrErtMUkjpd2WWQQlyudtLI89JpH5a8lDHvJnUkVXmkMPKcMeAg1peo70inrpRbm/ISFDwkhNX4NUSWxEo26WVFKisgc2ArWncSO3OthJvEs0nTju/bOT+NJKzJK++c5OovJWRIob2AwNsf6YXWJ3eFGbgXS4skgEGafaDGSifVONS/ZCQ/Q2YI5l8BdSS0ImwtTezehjiM9C3FG8fbVdykft/URTeEY918hlIZZFC9Yq0Rw6ns63nyxXtkTCYK6VuJv4NKvmMdgFMBHfBbRjb8JFxgoWW04RPmKfEaY2pgcZcT/OsL3GQ5baFrUN23iZZrvJ6pKjDJFXFvL8P3jIfvIGvNX7jsCaJvEAAAAASUVORK5CYII="
}
If you paste the Base64 into e.g https://codebeautify.org/base64-to-image-converter and point camera from your phone you will see the URL.
If you rendering this out it is easy i.e. in React (any JavaScript approach will be similar).
<img src={`data:image/png;base64,${image}`} />
I like this approach as if you are e.g. generate 2FA codes you can pass down both the random secret and the QR code - useful to have both as a backup if the user doesn't have access to a mobile device.
You can do this in a designated folder in your file-system easily and once you are done with the transfer, you can remove the file. But since, this operation is exposed over a rest api, concurrency and file collision can be an issue. To avoid that you can give unique to every file-name, that way same file-name collision can be avoided.
One approach could be to UUID for writing the file-name and storing the file with this name in the file-system. It will ensure collision doesn't occur.
String fileName = UUID.randomUUID().toString();
I'm using Spring Boot, Spring Data REST, Jasper Report (6.x).
I created a REST controller that should export a PDF report on disk and return a "ok" string to the client. So, it's a bit different from the usual use case in which the user what the PDF is sent back to the client.
According to best practice, I'm using the solution 4 of this reply: https://stackoverflow.com/a/27532493/2012635 for the "normal" use case in which the PDF is returned to the client:
#RequestMapping(value = "/refunds/{id}/export", method = RequestMethod.GET)
public ModelAndView exportPdf(#PathVariable("id") Long id, HttpServletRequest request, Locale locale) throws Exception {
Refund refund = refundRepository.findOne(id);
if (refund != null) {
ModelMap model = new ModelMap();
model.addAttribute("datasource", new JREmptyDataSource(1));
model.addAttribute("model", refund);
return new ModelAndView("RefundPdfView-IT", model);
} else {
throw new ResourceNotFoundException();
}
}
This approach is very clean, I've my mapping in the property file:
#REFUND
RefundPdfView-IT.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
RefundPdfView-IT.url=classpath:/reports/accounting/refunds/Refund-IT.jrxml
I'm wondering if I can reuse this approach to save the PDF on the disk in the server rather than send it back to the client.
I would like to reuse the mapping defined without hardcoding the position and names of reports.
Some advice would be appreciated.
First thing I would like to point out is you will need JasperExportManager.
exportReportToPdfFile(JasperPrint jasperPrint, java.lang.String destFileName)
to save a file locally in the server.
From your use case it is not clear why you want to save the file in server, I feel instead of saving the file you should save the search parameters. so that when you click on the parameters you will get/generate the pdf file again.
or alternatively you should use curl in the server and call the required url with parameters
I want to take Excel file from html input type="file" and pass that Excel file to my rest method java by http post method. I have a angular controller for that. I want to know how the controller should look like and what should be there in my rest method. I am using Apache POI to process the excel file.
You can have a angular method like this:
$scope.exelMethod = function (){
var excelObj = {};
excelObj.name = 'test';
excelObj.age = '20';
//you can write '/excel' as a rest web-service
$http.post('/excel,excelObj).success(function(response) {
console.log(response);// This will be a download path
//after this call the download function
});
}
In the middle layer you can write /excel service and map the excelObj from front end to a class view like this
public class ExcelView{
private String name;
private String age;
}
Now you can use this ExcelView class to map your data using POI. You will have to process the data and pass a download location of the file in the server to FE. In FE you will have to write a download function to download the file from the path you just got from the response.
#POST
#Path("/post")
#Consumes(MediaType.APPLICATION_JSON)
public Response getExcelData(ExcelView excelObj)
{ //this will be the service
}
if you need to know hot to write excel using poi check out this link
http://www.avajava.com/tutorials/lessons/how-do-i-write-to-an-excel-file-using-poi.html
I have a JSON that looks more or less like this:
{"id":"id","date":"date","csvdata":"csvdata".....}
where csvdata property is a big amount of data in JSON format too.
I was trying to POST this JSON using AJAX in Play! Framework 1.4.x so I sended just like that, but when I receive the data in the server side, the csvdata looks like [object Object] and stores it in my db.
My first thought to solve this was to send the csvdata json in string format to store it like a longtext, but when I try to do this, my request fails with the following error:
413 (Request Entity Too Large)
And Play's console show me this message:
Number of request parameters 3623 is higher than maximum of 1000, aborting. Can be configured using 'http.maxParams'
I also tried to add http.maxParams=5000 in application.conf but the only result is that Play's console says nothing and in my database this field is stored as null.
Can anyone help me, or maybe suggest another solution to my problem?
Thanks you so much in advance.
Is it possible that you sent "csvdata" as an array, not a string? Each element in the array would be a separate parameter. I have sent 100KB strings using AJAX and not run into the http.maxParams limit. You can check the contents of the request body using your browser's developer tools.
If your csvdata originates as a file on the client's machine, then the easiest way to send it is as a File. Your controller action would look like:
public static void upload(String id, Date date, File csv) {
...
}
When Play! binds a parameter to the File type, it writes the contents of the parameter to a temporary file which you can read in. (This avoids running out of memory if a large file is uploaded.) The File parameter type was designed for a normal form submit, but I have used it in AJAX when the browser supported some HTML5 features (File API and Form Data).
If I've got a link that looks like this from a tweet: https://t.co/xxxxxxxxxxx,
And I know that link contains and image. How do I extract that image from that post so I can use it on another page? I'm using twitter4j.
Thanks in advance
EDIT:
I thought it worked by doing the following:
public String getImageUrlFromPost(String url) throws TwitterException {
Query query = new Query(url);
QueryResult result = this.getTwitter().search(query);
System.out.println("The tweets found: " + result.getTweets() +" with query " + url);
for (Status status : result.getTweets()) {
for (MediaEntity mediaEntity : status.getMediaEntities()) {
return mediaEntity.getMediaURLHttps();
}
}
return null;
}
Unfortunately result.getTweets() is empty when I pass my t.co link :(
I'm afraid, but you won't be able to query for or retrieve images behind t.co-URLs programmatically via Twitter4J API that way.
Basically, there are at least two types of URL formats to reference resources in Twitter:
Every URL which has the format http://t.co/randomstringhere is a redirecting link to another resource in the web (most likely: a Web Page) and the actual web page might be structured totally different for every single referenced page. Hence, there is no generic way of inferring the xHTML structure of the referenced page and consequently no proper way to retrieve what you're looking for.
By contrast, Twitter uses the URL format http://pbs.twimg.com/media/anotherandomstring.png (or .jpg or other formats) to reference images that have been shared in tweets with attached media files (here: images). Only in this case you can use status.getMediaEntities() and mediaEntity.getMediaURLHttps() to retrieve the URL's binary content of the actual image.
Conclusion:
Sadly, at least in 2016, there is no generic way to retrieve resources (media files) behind http://t.co/... URLs referenced in tweets via Twitter4J.