non-static resources in Spring - java

I got Spring 2.5.6 and I'm trying to implement some stupid functionality within.
I have a photo directory somewhere in my server machine and I want to expose these photos to the user. What is the common solution for this issue?
P.S.
By now I'm writing my photos to the response using my own controller, and that is not very handy for me, cause I want to keep my photo's url nice and friendly (for example like /myServlet/images/012345.jpg).

Having your own controller is a fine solution. Here is a simplified copy from my PictureController:
#RequestMapping("/pictures/{filename}.{extension}")
public void getPicture(#PathVariable String filename,
#PathVariable String extension, OutputStream outputStream,
HttpServletResponse response) {
DateTime cachePeriod = new DateTime();
cachePeriod = cachePeriod.plusDays(5);
response.setDateHeader("Expires", cachePeriod.getMillis());
pictureService.writePicture(filename + "." + extension, outputStream);
}
Where pictureService simply does IOUtils.copy(imageStream, outputStream)

Related

Trying to save PDF form fields using iText (PdfAction.createSubmitForm). Losing existing javascript on jsp

I am trying to create a pdf where user fills the fields and saves the data. I created a 'save' button on pdf using iText. I am settig the action of the button using PdfAction.createSubmitForm. While I am getting the formfield values of pdf while saving, I am losing the existing javascript on my JSP due to this button. I am using PdfAction.SUBMIT_HTML_FORMAT in the save button. What am I doing wrong here?
Thanks
The issue has been resolved. If I redirect the servlet action, the JSP displayed is then working fine.
Below is the code
HttpServletResponse response ;
response.setContentType("text/html");
response.setContentLength(13);
String url = new URL(request.getScheme(),request.getServerName(), request.getServerPort(),request.getRequestURI()).toExternalForm();
String target = url+"?action="ServletAction";
response.addHeader("Refresh", new StringBuilder(target.length() + 5)
.append("0;url=").append(target).toString());
ServletOutputStream out = response.getOutputStream();
out.print("<html></html>");
I've read your answer and although it solves your problem (and clarifies the initial problem), you are solving the problem in a really bad way. You are sending an almost empty HTML file <html></html> to the browser and you're expecting that the browser will respect the Refresh header. This is so unprofessional!
Redirecting is done like this:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
String url = new URL(request.getScheme(),request.getServerName(), request.getServerPort(),request.getRequestURI()).toExternalForm();
String target = url+"?action=ServletAction";
response.sendRedirect(target);
}
Replace doGet with doPost if your code snippet was part of a doPost method.

spring file download using ResponseBody

Hello i'm trying create an application allowing me host any kind of file.
In order to do it i'm exececuting following magic:
#RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
#ResponseBody
public FileSystemResource
getFile(
#PathVariable("file_name") String fileName) {
System.out.println(fileName);
String filePath = "./files/";
return new FileSystemResource(new File(filePath+fileName));
}
But this approach brings three unwanted problems:
Some random data is beeing appended to the file
The file gets opened in the browser window instead of beeing
downloaded - i've tried to hack this using something like
produces = "application/octet-stream"
but it only resulted in 406 error.
The test.txt is beeing truncated into test, i found a walkaround in providing the app with test.txt/ as fileName but it looks a bit messy.
As stated on spring manual
As with #RequestBody, Spring converts the returned object to a
response body by using an HttpMessageConverter
I think your problem is spring doesn't come with a HttpMessageConverter than can process FileSystemResource.
A list of builtin HttpMessageConverter is available here. I suggest you try converting your response into byte array somehow, maybe it will pick ByteArrayHttpMessageConverter instead and help solve your issue
I used code like this to return image
#RequestMapping(value = "/image/{id}", method = RequestMethod.GET)
public String getImage(... HttpServletResponse response) {
response.setContentType(image/png);
(response.getOutputStream()).write(imageByteArray);
}
I think you have to define proper mime type and send your data to response.

Editing response content on doView()

I have a simple JSR 286 Portlet that displays a user manual (pure HTML code, not JSP).
Actually, my doView method, just contains this :
public class UserManualPortlet extends GenericPortlet
{
#Override
protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException
{
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
"/html/usermanual.html");
rd.include(request, response);
}
}
This works as expected, however I'm having trouble when including images. I'm aware that the path to images should be something like :
<img src='<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/html/image.jpg")%>'/>
However, my HTML file containing the user manual is used elsewhere, so I would like to preserve it as a pure HTML file.
Is there a way to dynamically replace my classic images urls by something like the example above ? Perhaps using the PrintWriter of the response ?
If such thing is not possible, I thing I would need to generate a JSP file during my Maven build.
Any solution or ideas are welcome.
With JSR-268 portlets you have a better way of referencing resources: create ResourceURL using renderResponse.createResourceURL() and then you set the resourceID in the ResourceURL. That should give more consistent results across all portlet containers.
That said, if you want to modify the generated content from your usermanual.html but you don't want to convert it to a JSP then, instead of using a request dispatcher, I would load the file contents on my own, parse it at the same time that I do the URL replacements and then print all the contents to the portlet's response.

ClientProtocolException when calling createAttachment using Ektorp to interface with CouchDB

I am using Ektorp (Java API for CouchDB) to store documents in my CouchDB instance. I am having trouble attaching images to documents. Every time I call createAttachment() it throws an ClientProtocolException.
Code Sample:
AttachmentInputStream attachment =
new AttachmentInputStream(attachmentId,
fileInputStream,
contentType,
file.length());
String rev = db.createAttachment(doc.getId(), attachment));
Does anyone know what's going wrong?
I had a similar problem using Ektorp. I resolved the issue by passing the latest revision number into the overloaded createAttachment method (db.createAttachment(doc.getId(), doc.getRevision(), attachment))). You could probably do the following:
AttachmentInputStream attachment =
new AttachmentInputStream(attachmentId,
fileInputStream,
contentType,
file.length());
String rev = db.createAttachment(doc.getId(), doc.getRevision(), attachment));
Good luck!

Generating a PDF using a PUT operation

I have a web application that can display a generated PDF file to the user using the following Java code on the server:
#Path("MyDocument.pdf/")
#GET
#Produces({"application/pdf"})
public StreamingOutput getPDF() throws Exception {
return new StreamingOutput() {
public void write(OutputStream output) throws IOException, WebApplicationException {
try {
PdfGenerator generator = new PdfGenerator(getEntity());
generator.generatePDF(output);
} catch (Exception e) {
logger.error("Error getting PDF file.", e);
throw new WebApplicationException(e);
}
}
};
}
This code takes advantage of the fact that I only need so much data from the front end in order to generate the PDF, so it can easily be done using a GET function.
However, I now want to return a PDF in a more dynamic way, and need a bunch more information from the front end in order to generate the PDF. In other areas, I'm sending similar amounts of data and persisting it to the data store using a PUT and #FormParams, such as:
#PUT
#Consumes({"application/x-www-form-urlencoded"})
public void put(#FormParam("name") String name,
#FormParam("details") String details,
#FormParam("moreDetails") String moreDetails...
So, because of the amount of data I need to pass from the front end, I can't use a GET function with just query parameters.
I'm using Dojo on the front-end, and all of the dojo interactions really don't know what to do with a PDF returned from a PUT operation.
I'd like to not have to do this in two steps (persist the data sent in the put, and then request the PDF) simply because the PDF is more "transient" in this uses case, and I don't want the data taking up space in my data store.
Is there a way to do this, or am I thinking about things all wrong?
Thanks.
I can't quite understand what do you need to accomplish - looks like you want to submit some data to persist it and then return pdf as a result? This should be straightforward, doesn't need to be 2 steps, just submit, on the submit save the data and return PDF.
Is this your problem? Can you clarify?
P.S.
Ok, you need to do the following in your servlet:
response.setHeader("Content-disposition",
"attachment; filename=" +
"Example.pdf" );
response.setContentType( "application/pdf" );
Set the "content-length" on the response, otherwise the Acrobat Reader plugin may not work properly, ex. response.setContentLength(bos.size());
If you provide output in JSP you can do this:
<%# page contentType="application/pdf" %>

Categories