Downloading PDF file with additional data from a Servlet - java

How to download PDF file with other data on the same HTTP request to a Servlet?
For example, I have a PDF file in my server and I want to respond to a request with that PDF file and other data like myname and myage, etc on the same request. Can it be done on the same request?

The Java Servlet API does not provide any in-built mechanism for multi-part responses (which is the name of the feature that you are looking for). The Servlet API documentation hints at how this can be achieved, in the ServletResponse API doc:
To send binary data in a MIME body
response, use the ServletOutputStream
returned by getOutputStream(). To send
character data, use the PrintWriter
object returned by getWriter(). To mix
binary and text data, for example, to
create a multipart response, use a
ServletOutputStream and manage the
character sections manually.
Multipart responses are created by setting the content-type (the MIME type) of the response to "multipart/x-mixed-replace;boundary=xyz". The value xyz is arbitrary and is used to delineate the several sections of the response. An implementation of a Multipart Response class can be found in the book - "Java Servlet Programming" by Jason Hunter, and also in the KickJava site (please read the license before using it in your project).

If this other data is just text, perhaps you could it include it as headers of the response

Related

Capturing Response Size - HttpServlet

I have an application where the users are accessing a servlet file which will read a .pdf file conditionally and send the .pdf file as response to the users request. The servlet code does not sets the content length on the response header.
In the above scenario I want to capture the Response Size of the each user request without making any changes in the servlet code.
At the same time I do not want to use the HttpServletResponseWrapper for some other reasons.
Please suggest me on the possible ways to achieve this.
Thanks in advance.
Every container supports Web Access Logging. Look for that and enable it. It will log the response content length along with other request and response parameters.

How to retrieve metadata associated with a video or image sent from a RESTful web service?

I have the controller shown below:
#RequestMapping(value = "/videos/{id}",
headers = "Accept=image/jpeg, image/jpg, image/png, video/mp4",
method = RequestMethod.GET)
public ResponseEntity<byte[]> loadVideo(#PathVariable("id") long campaignId,
Principal principal) throws IOException {
This controller returns a byte stream of the media associated with the given id. It works fine. The only issue I'm having is loading this videos associated metadata (title, description, view count, etc...) as I'm sending back an array of bytes, so I'm not too sure where to put the meta data.
Should I place the metadata in the response headers?
Should I have two separate calls, one for the video (byte steam) and
another call which returns an object containing the meta data?
Or is there a better way to go about this than either of the two
options above?
As my comment was already lenghty I decided to repost it here again:
If you deal with certain media-types like image/jpg or video/mp4 you should include the metadata as headers as the payload of the response should only include the bytes of the respective file. This also enables a lookup of the metadata without having to download the bytes of the actual file via a simple HEAD request.
Certain API provides, howerver, define their own media-type or send a JSON or XML based response to the client. In this cases, the payload contains often a predefined structure which includes the bytes of the file as a base64 encoded string as well as the metadata as plain text. These APIs argument that sending multiple files at once is easier this way then to handle multipart content.

what is the use of "response.setContentType("text/html")" in servlet

public class HelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException{
**response.setContentType("text/html");**
PrintWriter pw = response.getWriter();
pw.println("<html>");
pw.println("<head><title>Hello World</title></title>");
pw.println("<body>");
pw.println("<h1>Hello World</h1>");
pw.println("</body></html>");
}
}
Content types are included in HTTP responses because the same, byte for byte sequence of values in the content could be interpreted in more than one way.(*)
Remember that http can transport more than just HTML (js, css and images are obvious examples), and in some cases, the receiver will not know what type of object it's going to receive.
(*) the obvious one here is XHTML - which is XML. If it's served with a content type of application/xml, the receiver ought to just treat it as XML. If it's served up as application/xhtml+xml, then it ought to be treated as XHTML.
From JavaEE docs ServletResponse#setContentType
Sets the content type of the response being sent to the client, if the response has not been committed yet.
The given content type may include a character encoding specification, for example,
response.setContentType("text/html;charset=UTF-8");
The response's character encoding is only set from the given content type if this method is called before getWriter is called.
This method may be called repeatedly to change content type and character encoding.
This method has no effect if called after the response has been committed. It does not set the response's character encoding if it is called after getWriter has been called or after the response has been committed.
Containers must communicate the content type and the character encoding used for the servlet response's writer to the client if the protocol provides a way for doing so. In the case of HTTP, the Content-Type header is used.
It means what type of response you want to send to client, some content types like :
res.setContentType("image/gif");
res.setContentType("application/pdf");
res.setContentType("application/zip");
You have to tell the browser what you are sending back so that the
browser can take appropriate action like launching a PDF viewer if its a PDF that is being received or launching a video
player to play video file ,rendering the HTML if the content type is simple html response, save the bytes of the response as a downloaded file, etc.
some common MIME types are text/html,application/pdf,video/quicktime,application/java,image/jpeg,application/jar etc
In your case since you are sending HTML response to client you will have to set the content type as text/html
response.setContentType("text/html");
Above code would be include in "HTTP response" to inform the browser about the format of the response, so that the browser can interpret it.
It is one of the MIME type, in this case you are reponse header MIME type to text/html it means it displays html type. It is a information to browser. There are other types you can set to display excel, zip etc. Please see MIME Type for more information

How can I pass JSON as well as File to REST API in JAVA?

My main question is how can I pass JSON as well as File to post request to REST API? What needs in Spring framework to work as client and wait for response by passing post with JSON and File?
Options:
Do I need to use FileRepresentation with ClientResource? But how can I pass file as well as JSON?
By using RestTemplate for passing both JSON as well as File? How it can be used for posting JSON as well as File?
Any other option is available?
Sounds like an awful resource you're trying to expose. My suggestion is to separate them into 2 different requests. Maybe the JSON has the URI for the file to then be requested…
From a REST(ish) perspective, it sounds like the resource you are passing is a multipart/mixed content-type. One subtype will be application/json, and one will be whatever type the file is. Either or both could be base64 encoded.
You may need to write specific providers to serialize/deserialize this data. Depending on the particular REST framework, this article may help.
An alternative is to create a single class that encapsulates both the json and the file data. Then, write a provider specific to that class. You could optionally create a new content-type for it, such as "application/x-combo-file-json".
You basically have three choices:
Base64 encode the file, at the expense of increasing the data size
by around 33%.
Send the file first in a multipart/form-data POST,
and return an ID to the client. The client then sends the metadata
with the ID, and the server re-associates the file and the metadata.
Send the metadata first, and return an ID to the client. The client
then sends the file with the ID, and the server re-associates the
file and the metadata.

Cannot Compress Java Server Response Sent To JSP

I am having trouble in returning compressed response (GZip) from my Java Servlet, to a JSP.
Flow :
Request comes to java servlet
Process the request, and create a JSON object, with the response
Convert the JSON object to string
Compress the response string with GZip
The compressed response string is set as attribute in the request object and control passed to JSP
In the JSP, the response string (compressed) is printed on screen
Precautions :
Request object has "Accepting-Encoding" set with "gzip"
Response header has "Content-Encoding" set to "gzip"
Response content type is set to "application/json"
Response character encoding is set to "ISO-8859-1"
Result :
Firefox shows "Content Encoding Error"
Chrome shows "Error 330 (net::ERR_CONTENT_DECODING_FAILED): Unknown error."
Can anyone help point me out, in the right direction please?
The compressed response string is set as attribute in the request object and control passed to JSP
You shouldn't have forwarded a JSON response to a JSP. You should have printed the JSON plain to the response and have the JavaScript/Ajax code in your JSP Android app to call the URL of the servlet which returns the JSON. See also How to use Servlets and Ajax?.
As to the GZIP compression, you shouldn't do it yourself. Let the server do itself.
Fix your code to remove all manual attempts to compress the response, it should end up to basically look like this:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String json = createItSomehow();
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
That's all, if you let your Android app call the URL of the servlet, it'll retrieve the JSON string.
Finally edit the server configuration to turn on automatic GZIP compression. In case of for example Tomcat, that would be a matter of adding compression="on" to the <Connector> element in Tomcat's /conf/server.xml file:
<Connector ... compression="on">
As per the documentation, the compressable mime types defaults to text/html,text/xml,text/plain. You can configure this to add application/json.
<Connector ... compression="on" compressableMimeType="text/html,text/xml,text/plain,application/json">
Unrelated to the concrete problem, the response character encoding must be set to UTF-8 which is as per the JSON specification.
JSPs are for rendering textual data to the client. GZIP is binary data, even if it is compressed text underneath.
I suggest using a GZIP servlet filter to compress your data on the fly, instead of doing it programmatically in your business logic.
See this prior question for how to get hold of one off-the shelf: Which compression (is GZIP the most popular) servlet filter would you suggest?
Failing that, then write your own servlet filter that does the same thing.

Categories

Resources