StreamingResolution Stripes - java

Could anyone help me with java Framework - stripes?
I try to upload image with stripes:file, resize on the server and return with new StreamingResolution return ("image / jpeg"...
I dont now exactly how to send with StreamingResolution and how can I load image after stripes:file element on jsp?
Many Thanks

Well if you want to show the image on the page after uploading, there are a couple of things to deal with. First, the "POST" is going to have to have some sort of result, and that result probably won't be the image data. That is, having your action (your "event handler", as Stripes people call them) return a StreamingResolution doesn't really make sense unless you just want the user to be able to save the image like a downloaded file.
Thus, your image upload "POST" might involve just a plain resolution that forwards to a result page. Inside that page, you can put an HTML <img> tag that has a "src" set to another Stripes action. Now that action will return the StreamingResolution for your image data.
One problem to solve is where to keep the image data across the two HTML transactions. For that, I'd use a Stripes "flash scope" because it's pretty simple. If your server code is going to store the image in a database anyway, of course, your image action URL would simply include some sort of identifying information.
Assuming you can find the image data, all your server-side handler has to do is to create a StreamingResolution instance that has an implementation for the stream() method. That takes a single parameter (the HttpServletResponse). From that, you'd open up an output stream with response.getOutputStream(), copy the image data out to that, and then close the stream. There's really not much to it. Here's an example that sends out a simple file, but for you the main difference would be keeping track of the image data and of course a different MIME type:
public Resolution image() {
return new StreamingResolution("text/plain") {
public void stream(final HttpServletResponse response) {
InputStream sample = null;
try {
sample = getResourceAsStream(SAMPLE + getContext().getLocale().toString());
if (sample == null) sample = getResourceAsStream(SAMPLE + "en_US");
final OutputStream out = response.getOutputStream();
final byte buffer[] = new byte[8192];
out.write((HEADER + "\n").getBytes());
for (int rc = sample.read(buffer); rc > 0; rc = sample.read(buffer))
out.write(buffer, 0, rc);
}
finally {
if (sample != null) try { sample.close(); } catch (IOException ioe) { }
}
}
};
}
You'd want to also call setAttachment(false); before you start writing out the image data. This example is for a file download, so in my case I want it to be an attachment (and that's the default). If you're responding to a "GET" generated from an <img> tag, however, you don't want it to look like an attachment.

Related

Not able to generate multiple documents using ServletOutputStream in Java [duplicate]

For example, i would like to download one zip file and one csv file in one response. Is there any way other than compressing these two files in one zip file.
Although ServletResponse is not meant to do this, we could programmatically tweak it to send multiple files, which all client browsers except IE seems to handle properly. A sample code snippet is given below.
response.setContentType("multipart/x-mixed-replace;boundary=END");
ServletOutputStream out = response.getOutputStream();
out.println("--END");
for(File f:files){
FileInputStream fis = new FileInputStream(file);
BufferedInputStream fif = new BufferedInputStream(fis);
int data = 0;
out.println("--END");
while ((data = fif.read()) != -1) {
out.write(data);
}
fif.close();
out.println("--END");
out.flush();
}
out.flush();
out.println("--END--");
out.close();
This will not work in IE browsers.
N.B - Try Catch blocks not included
Code developed by Jason Hunter to handle servlet request and response having multiple parts has been the defacto since years. You can find it at servlets.com
No you can not do that. The reason is that whenever you want to sent any data in request you use steam available in request and retrive this data using request.getRequestParameter("streamParamName").getInputStream(), also please make a note if you have already consumed this stream once you will not be able to get it again.
The example mentioned above is a tweak that google also uses in sending multipart email with multiple attachments. To achieve that they define boundaries for each attachment and client have to take care of these boundaries while retrieving this information and rendering it.

How to analyze a photo sent through JSON

I have a Web Service that takes a photo through a POST statement and returns a modified copy of that photo back. We are making changes to the way it processes the photo, and I want to verify that the photo at least has different properties coming back than it did before our changes went into effect.
The photo is being returned as a byte stream inside one of the fields of a JSON object. I can analyze the JSON object pretty easily, but I'm trying to figure out how to get the byte stream into an Java image object so that I can get its dimensions.
Possible duplicate of this question
... I'm trying to figure out how to get the byte stream into an Java image object so that i can get its dimensions.
I'd suggest using a BufferedImage in the following format/snippet. Note: I load my image in from disk for the example and use try-with-resources (which you may revert to 1.6-prior if needed).
String fp = "C:\\Users\\Nick\\Desktop\\test.png";
try (FileInputStream fis = new FileInputStream(new File(fp));
BufferedInputStream bis = new BufferedInputStream(fis)) {
BufferedImage img = ImageIO.read(bis);
final int w = img.getWidth(null);
final int h = img.getHeight(null);
}
You can use:
OS Process Sampler and 3rd-party tool like ImageMagick
JSR223 Test Elements, to wit
JSR223 PreProcessor to get information on the photo, you're trying to upload
JSR223 PostProcessor to get information on the photo, returned by the Web Service
JSR223 Assertion to compare two photos
Depending on what parameters you need to compare you can use ImageIO API (out of the box, bundled with JDK), Commons Imaging, ImageJ and so on.

Scrape website for one data

I would like to extract the value of <div class="score">4.1</div> from a website with JAVA (Android). I tried Jsoup and even though it couldn't be simpler to use, it gives me the value in 8 seconds, which is very slow. You need to know, the page source of the site has 300,000 characters and this <div> is somewhere in the middle.
Even using HttpClient and getting the source into a StringBuilder then going through the whole string until the score part is found is faster (3-4 seconds).
I couldn't try out HtmlUnit as it requires a massive amount of jar files and after a while Eclipse always pissed itself in its confusion.
Is there a faster way?
You may simply send a XMLhttpRequest and then search the response using search() function. I think this would be much faster.
Similar Question: Retrieving source code using XMLhttpRequest in javascript
To make the search more fast, you can simply use indexOf([sting to search],[starting index]) and specify the starting index (it doesn't needs to be very accurate, you just have to decrease your search area).
Here is what I did. The problem was that I read the webpage line by line then glued them together into a StringBuilder and searched for the specific part. Then I asked myself: why do I read the page line by line then glue them together? So instead I read the page into a ByteArray and converted it into a String. The scraping time became less than a second!
try
{
InputStream is = new URL(url).openStream();
outputDoc = new ByteArrayOutputStream();
byte buf[]=new byte[1024];
int len;
while((len=is.read(buf))>0)
{
outputDoc.write(buf,0, len);
}
outputDoc.close();
} catch(Exception e) { e.printStackTrace(); }
try {
page = new String(outputDoc.toByteArray(), "UTF-8");
//here I used str.indexOf to find the part
}

Can i attach multiple attachments in one HttpServletResponse

For example, i would like to download one zip file and one csv file in one response. Is there any way other than compressing these two files in one zip file.
Although ServletResponse is not meant to do this, we could programmatically tweak it to send multiple files, which all client browsers except IE seems to handle properly. A sample code snippet is given below.
response.setContentType("multipart/x-mixed-replace;boundary=END");
ServletOutputStream out = response.getOutputStream();
out.println("--END");
for(File f:files){
FileInputStream fis = new FileInputStream(file);
BufferedInputStream fif = new BufferedInputStream(fis);
int data = 0;
out.println("--END");
while ((data = fif.read()) != -1) {
out.write(data);
}
fif.close();
out.println("--END");
out.flush();
}
out.flush();
out.println("--END--");
out.close();
This will not work in IE browsers.
N.B - Try Catch blocks not included
Code developed by Jason Hunter to handle servlet request and response having multiple parts has been the defacto since years. You can find it at servlets.com
No you can not do that. The reason is that whenever you want to sent any data in request you use steam available in request and retrive this data using request.getRequestParameter("streamParamName").getInputStream(), also please make a note if you have already consumed this stream once you will not be able to get it again.
The example mentioned above is a tweak that google also uses in sending multipart email with multiple attachments. To achieve that they define boundaries for each attachment and client have to take care of these boundaries while retrieving this information and rendering it.

How can I display a JFreeChart in web browser with Stripes Framework

This is the situation:
My 'metrics.jsp' page submits a couple variables that are needed to create the chart. The 'ProjectActionBean.java' calls down to a few other java classes that create the JFreeChart. I can display the chart in a pop-up but I want it to be displayed in the original browser window.
JFreeChart placeChart = ChartFactory.createBarChart(
"ChartName",
"", //x-axis label
"", //y-axis label
dataset,
PlotOrientation.VERTICAL,
false, //legend
true, //tooltype
false); //generate urls
ChartFrame frame = new ChartFrame(name, placeChart);
frame.pack();
frame.setVisible(true);
I've written an application like this, so I can assure you it's feasible :)
First, you need to get rid of anything that's GUI. You simply don't have a GUI on the server. This means your ChartFrame frame gets dumped. My main routine for creating a chart looks like this:
private void createChart(XYPlot plot, String fileName, String caption) throws IOException {
JFreeChart chart = new JFreeChart(caption, plot);
chart.addSubtitle(this.subtitle);
if (plot.getRangeAxis() instanceof LogarithmicAxis) {
chart.addSubtitle(1, new TextTitle("(logarithmische Skala)"));
}
File file = new File(fileName);
file.delete();
ChartUtilities.saveChartAsPNG(file, chart, CHART_WIDTH, CHART_HEIGHT);
}
This creates a file you can serve up as an <img> from your Web page. Alternatively (but a bit more advanced), you can use ChartUtilities to create a stream that you can serve up in response to a request for the image URL.
Another bit of magic that's required is to tell Java that you're running graphics code without a GUI. You need to set the environment variable
-Djava.awt.headless=true
For a Web app server like Tomcat, this goes into the Tomcat startup script.
Update
okay yeah doesn't the 'ChartUtilities.saveChartAsPNG();' just save the chart onto the file system? I want the user to be able to input the variables and then a chart be displayed directly back to them in the browser.
As long as you have just one user, writing the images to the file system will work fine for the scenario you describe. In fact, that's how my first version worked: I had 4 <img> tags in my HTML response page from the form where the user specified the parameters; and those pointed at the names of the 4 files with my images. So long as you finish writing those files before returning the answer to the user, this works fine.
Problems appear when you have multiple users. They can end up viewing the charts specified by the other user. There are possible workarounds with encoding the user's ID or session into the chart file names, but that gets ugly real fast. There is a better way, based on on-demand dynamic generation of each image, singly.
I don't know how much you know about HTML/HTTP, so I hope I'm not going to bore you with this:
For any given HTTP request, you can only return a single stream of data. Typically, that's a HTML page, i.e. a stream of text. If you want images in your HTML page, you insert <img> links with different URLs into your HTML page, and you're still just returning a page full of text. The browser then goes ahead and requests the images by firing off requests for those URLs mentioned in the <img> tags. This is pretty easy when your images are just files in the file system. If you want dynamically generated images such as charts, then you have to think up a URL for each kind of image you want to generate, and map each of those URLs to a servlet that knows how to generate such an image.
My app had 4 different charts on one page, so my HTML page had 4 <img> tags with 4 different URLs that all mapped to the same chart-generating servlet, but there were some parameters in the URL that told the servlet what kind of chart was wanted. Upon receiving the request, the servlet would do the JFreeChart magic and then it would use ChartUtilities.writeChartAsPNG() to dump the generated image to the servlet's output stream.
You need to write a servlet which writes image (byte stream) into the output stream to the client. There are no need for creating files. Basically something like this should work:
public class ChartServlet extends HttpServlet {
#Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
JFreeChart chart = .. // create your chart
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ChartUtilities.writeChartAsPNG(bos, chart, width, height);
response.setContentType("image/png");
OutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(bos.toByteArray());
out.flush();
out.close();
}
}
Then map it to some url in your web.xml and use from "img" tag in HTML/JSP. Obviously you can pass parameters to it etc.
If you want to stay within the Stripes framework you can use a custom extension of the StreamingResolution, thusly:
Create a new normal ActionBean implementation that will represent the URL of your chart (to be included in your img tag):
#DefaultHandler
public Resolution view() {
JFreeChart chart = ...
return new ChartStreamingResolution(chart);
}
The custom StreamingResolution then looks like this:
public class ChartStreamingResolution extends StreamingResolution {
private JFreeChart chart;
public ChartStreamingResolution(JFreeChart chart) {
super("image/png");
this.chart = chart;
}
#Override
public void stream(HttpServletResponse response) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ChartUtilities.writeChartAsPNG(bos, chart, 400, 200);
OutputStream out = new BufferedOutputStream(response.getOutputStream());
out.write(bos.toByteArray());
out.flush();
out.close();
} catch (Exception e) {
//something sensible
}
}
}

Categories

Resources