How to make files download instead of opening in browser? - java

I am a new bie, i want files to get downloaded when user clicks on download option its opening in the browser instead of download option like save as/open.Here i referred for the same and every where they have suggested to use
Response.AddHeader("Content-disposition", "attachment; filename=" + Name);
But i don't know where and how to use.
Actually i'm getting the url value from query written which return url as one of the object of bean stored in arraylist(This list is having other values also with url ).
I am having the url values inside the arraylist as bean as like
type=.pdf
release date=12/3/08
name=hai.pdf
url=/files/en/soft/doc/docs/hai.pdf
I am getting this array list in my controller like this
ArrayList details = dao.getdetails(Bean.getNumber());
and pass this into view like this
Map.put("details", details);
modelView.setViewName("details_list");
modelView.addAllObjects(Map);
return modelView;
in jsp i have iterated this array list and diplays the content like this
Type name Release Date
.txt hai.pdf May 21st 2012 Download
.txt hello.txt May 21st 2012 Download
For download i have used like this in jsp
<td colspan="2" valign="top">
<a href="${details.Url}"/>
<img src="/images/download.gif" alt="Download" border="0" align="right"></a>
</td>
here on click of download its opening in browser.I need this to be downloaded instead.
Please help me in how to use or handle
response.setHeader("Content-Disposition", "attachment;");
where to add the above for my requirement or if i can do with any java script also.Please help me in solving the above.

Here is one way of doing it:
Create a web Filter (or this way )
Map this filter to the PDF URL.
In the doFilter() method, set the response header for content download.
Example :
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String name = request.getAttribute("filename");
response.addHeader("Content-disposition", "attachment; filename=" + name);
chain.doFilter(request, response);
}
You can set the filename as an request attribute (reqest.setAttribute()) from your controller class
Filters are pretty standard in Java web stack.

It's depend on the header which browser get in response.
Suppose if header is image/png then browser will show it. Same way if you send same image with application/octet-stream then browser will force to download it.
take a look http://en.wikipedia.org/wiki/Byte_stream
In a project I have figure out that sending request from browser are different.
If you upload a image from Firefox or IE then it's will upload them as image/png wherever chrome upload them as application/octet-stream.

just try to add header
response.setHeader("Content-Type: application/force-download");

Related

How to Map Servlet Actions to JSP Path with Annotations?

I have a simple Maven servlet/jsp application that I deploy to a local Tomcat 9 (via Eclipse). JSP pages are stored under root folder (src\main\webapp\*.jsp) which when Maven installs a WAR, they go under the root folder (MyAppContext\*.jsp along side MyAppContext\META-INF\ and MyAppContext\WEB-INF\).
The servlets' URL patterns are annotated for each servlet, e.g. /doactionone, /doactiontwo, etc. Most servlets perform the dispatching to various JSP pages, but I do have a direct anchor link on one.
I wanted to move these JSP pages into their own respective directory, so I moved them to src\main\webapp\jsp\*.jsp folder, and when the Maven install is run, they get placed under MyAppContext\jsp\.
The only entry I have in web.xml is a welcome file that after relocating the JSP files, it points to jsp\doactionone.jsp which loads that corresponding JSP page. This page contains a simple form:
<form action="doactionone" method="post">
...
<a href="jsp/doactiontwo.jsp">
<input type="submit" />...
</form>
The submission on this page actually calls the right servlet (the one defined with doactionone URL pattern). I also have a link that takes the user to the second page (doactiontwo.jsp).
However, when I navigate to that second page via this link, which has another simple form (see below), and perform the submission (post), I see in browser's debugging that the URL request is http://localhost:8080/MyAppContext/jsp/doactiontwo which, for obvious reason, would return a 404 status (and get no hit to this servlet's doPost() (or doGet()) methods either).
<form action="doactiontwo" method="post">
...
<input type="submit" />...
</form>
If I try to modify the second servlet's URL pattern to /jsp/doactiontwo, I can hit the servlet, but when doactiontwo actually dispatches/forwards the request after processing to the first servlet (doactionone) with:
RequestDispatcher rd = request.getRequestDispatcher("doactionone.jsp");
rd.forward(request, response);
when it gets loaded, when hover over the URL on the first page that initially was pointing to the second JSP page (<a href="jsp/doactiontwo.jsp">), now actually points to:
jsp/jsp/doactiontwo.jsp
The funny part is that the source code of doactionone.jsp still shows it as jsp/doactiontwo.jsp, but hovering over it shows http://localhost:8080/MyAppContext/jsp/jsp/doactiontwo, and when clicked, it obviously results in 404 status.
Can somebody explain why, first of all, the submission on the second JSP page requires the servlet to have a pattern of /jsp/doactiontwo to work rather than /doactiontwo? And is there a way around to avoid appending /jsp to the URL pattern?
And second, why when the second servlet processes the request and dispatches/forwards it to the first page, the URL now contains two jsp/'s?
You need to change your design to allow the controllers, a.k.a. Servlets, to drive your application. In this particular case, use the URL Pattern of second Servlet (doactiontwo) in place of you link:
#WebServlet(urlPatterns = { "doactiontwo" }
public class DoActionTwoServlet extends HttpServlet { /* ... */ }
<form action="doactionone" method="post">
...
<a href="doactiontwo"> <!-- This should match your second servlet's URL pattern -->
<input type="submit" />...
</form>
Now, since the default method when anchor link is invoked is GET, you need to overwrite DoActionTwoServlet's doGet() method, and forward those requests to an actual doactiontwo.jsp:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("jsp/doactiontwo.jsp");
rd.forward(request, response);
}

Error while displaying image in jsp

First of all, i read tons of posts regarding this but i can't manage to get this working.
I'm really new to jsp and web apps. All i wanna do is to display a simple image.
I have this code in the servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession sesion = request.getSession();
String filePath = getServletContext().getRealPath("image.jpg");
System.out.println(filePath);
sesion.setAttribute("image", filePath);
response.sendRedirect("products.jsp");
}
And this code in the jsp:
<img alt="logo" src="${image}"/>
And the folders in my web app are this:
folders image
And finally, when my page loads, this is what i get:
image does not display
I wonder what is the error here? Why it is so complicated (maybe it's not, but i really tried many ways and non of them worked) to display a simple image?
Thanks in advance for your help!
PS: the folder is correct, it prints without problem in the println()
getRealPath() gets you the real path in the file system.
When you reference any resource (image, js, css) inside a web it is supposed to be accesible via web.
If you click "view source code" in your browser you'll probably see the fil system path in the tag:
<img alt="logo" src="C:/whatever-your-path-is/image.jpg"/>
But what you need is the url path (full or relative) of the resource.
Try this instead:
sesion.setAttribute("image", "resources/images/image.jpg");

uploading files by url

I need to implement a servlet that uploads files to a server, I realize everyone says it has to be a POST method in regard to uploading files and not with GET method. However is there a way to upload a file and have the parameters of the request show up in the url even if the request is coming from POST method? If not, is there another approach?
Currently my servlet using post method is http://example.com/FileUpload/UploadFile
What I want is somehting like http://example.com/FileUpload/UploadFile?id=125&fileNum=5
Thanks for your input.
Simply POST to
http://example.com/FileUpload/UploadFile?id=125&fileNum=5
instead of
http://example.com/FileUpload/UploadFile
There is no such restriction that you cannot post to an URL having parameters. You can process the post data as you are doing now, plus, you can get the get parameters also.
I think it would not be an elegant solution, but you could use JavaScript to alter the action of the form element before submitting it to include querystring parameters.
The form will be something like:
<form method="POST" id="myForm" onSubmit="submitMyForm(this)>
<input type="text" id="id">
Then you will need JavaScript to change the action element of the form:
function submitMyForm(theForm) {
theForm.action="http://example.com/FileUpload/UploadFile?id=" +
getElementById("id").value;
theForm.submit();
}
Is there some reason you cannot just submit the parameters with post and pull them out on the server side?
Alternatively, if you do a multipart/form-data post you can include multiple parameters along with your file. The parameters are sent as part of the post body, along with the file.
You can send parameters and files in the POST. For example in the html you can have a form with this values, they can be of hidden type.
In the servlet you can get the values in the same way you do using the GET.
It is also better to use the POST method because the user can't change the value in the URL direction bar.

How to insert JSP functionality in Servlets?

How can I use Servlets to access the HTML uses of having JSP without having to have all my client-facing pages called *.jsp?
I would rather do this than using all the response.write() stuff because I think it is easier to read and maintain when it is all clean "HTML".
Is this is fair assesment?
EDIT: What I'm going for is having the Servlets output things to the screen without having to redirect to a .jsp file.
In this way, I could write all the JSP stuff, but when it comes time to display it, the page the URL the user sees is essentially, "http://blah.com/posts/post-id" which is the address of the servlet and not "http://blah.com/posts.jsp?pos=post-id".
But I would still write all presentation logic in an external .jsp.
Just hide the JSP away in /WEB-INF folder so that noone can access it directly and create a servlet which forwards the request to this JSP file. Don't do a redirect, else you will see the new URL being reflected in the address bar. E.g.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String postId = request.getPathInfo();
// Do your business thing here. Any results can be placed in request scope. E.g.
request.setAttribute("post", post); // post is a bean containing information you'd like to display in JSP.
// Then forward request to JSP file.
request.getRequestDispatcher("/WEB-INF/posts.jsp").forward(request, response);
}
Map this servlet on an url-pattern of /posts/*.
In the /WEB-INF/posts.jsp make use of taglibs to control page flow and EL to access the data. E.g.
<h2>${post.title}</h2>
<p><fmt:formatDate value="${post.date}" type="date" /> - ${post.message}</p>
Finally just invoke the servlet by http://example.com/posts/postid. The /postid part will be available by HttpServletRequest#getPathInfo(). You need to parse the value yourself and do the business thing with it.
I'm not entirely sure what you're asking here. You can ge servlets themselves to write HTML, but that's not clean at all.
An alternative is to get your servlets to create HTML via a templating engine, such as Velocity or Freemarker. The syntax in the templates may be cleaner for your particular application, if less fully featured.
Back in ancient times (think '98...) this was called a "Model 2 architecture": a servlet received the request, processed it, and handed the request over to a JSP page that handled the view.
See this article for one example of how this is done, or simply search for "JSP Model 2".
Edit: for that, you can use RequestDispatcher.include() instead of forward() as described in the previous article. The rest should still be applicable.
If I understand correctly you want to hide *.jsp extension from user, right?
In that case when your Servlet redirects to a jsp page have it do this:
RequestDispatcher disp = request.getRequestDispatcher("hidden.jsp");
disp.forward(request,response);
By using Request Dispatcher instead of redirect you "hide" your .jsp extension behind the servlet name. However in case your JSP page redirects to another JSP page this won't work.
If you want the .jsp file to be visible use response.encodeURL or response.sendRedirect
I think you're looking for the Front Controller Pattern - this is the basis of "JSP Model 2" web apps (as #andri mentioned) and pretty much all the (hundreds?) of Java web frameworks.

doGet and doPost in Servlets

I've developed an HTML page that sends information to a Servlet. In the Servlet, I am using the methods doGet() and doPost():
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
In the html page code that calls the Servlet is:
<form action="identification" method="post" enctype="multipart/form-data">
User Name: <input type="text" name="realname">
Password: <input type="password" name="mypassword">
<input type="submit" value="Identification">
</form>
When I use method = "get" in the Servlet, I get the value of id and password, however when using method = "post", id and password are set to null. Why don't I get the values in this case?
Another thing I'd like to know is how to use the data generated or validated by the Servlet. For example, if the Servlet shown above authenticates the user, I'd like to print the user id in my HTML page. I should be able to send the string 'id' as a response and use this info in my HTML page. Is it possible?
Introduction
You should use doGet() when you want to intercept on HTTP GET requests. You should use doPost() when you want to intercept on HTTP POST requests. That's all. Do not port the one to the other or vice versa (such as in Netbeans' unfortunate auto-generated processRequest() method). This makes no utter sense.
GET
Usually, HTTP GET requests are idempotent. I.e. you get exactly the same result everytime you execute the request (leaving authorization/authentication and the time-sensitive nature of the page —search results, last news, etc— outside consideration). We can talk about a bookmarkable request. Clicking a link, clicking a bookmark, entering raw URL in browser address bar, etcetera will all fire a HTTP GET request. If a Servlet is listening on the URL in question, then its doGet() method will be called. It's usually used to preprocess a request. I.e. doing some business stuff before presenting the HTML output from a JSP, such as gathering data for display in a table.
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#EJB
private ProductService productService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
Note that the JSP file is explicitly placed in /WEB-INF folder in order to prevent endusers being able to access it directly without invoking the preprocessing servlet (and thus end up getting confused by seeing an empty table).
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td>detail</td>
</tr>
</c:forEach>
</table>
Also view/edit detail links as shown in last column above are usually idempotent.
#WebServlet("/product")
public class ProductServlet extends HttpServlet {
#EJB
private ProductService productService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Product product = productService.find(request.getParameter("id"));
request.setAttribute("product", product); // Will be available as ${product} in JSP
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="productImage?id=${product.id}" /></dd>
</dl>
POST
HTTP POST requests are not idempotent. If the enduser has submitted a POST form on an URL beforehand, which hasn't performed a redirect, then the URL is not necessarily bookmarkable. The submitted form data is not reflected in the URL. Copypasting the URL into a new browser window/tab may not necessarily yield exactly the same result as after the form submit. Such an URL is then not bookmarkable. If a Servlet is listening on the URL in question, then its doPost() will be called. It's usually used to postprocess a request. I.e. gathering data from a submitted HTML form and doing some business stuff with it (conversion, validation, saving in DB, etcetera). Finally usually the result is presented as HTML from the forwarded JSP page.
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
...which can be used in combination with this piece of Servlet:
#WebServlet("/login")
public class LoginServlet extends HttpServlet {
#EJB
private UserService userService;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("home");
}
else {
request.setAttribute("error", "Unknown user, please try again");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
You see, if the User is found in DB (i.e. username and password are valid), then the User will be put in session scope (i.e. "logged in") and the servlet will redirect to some main page (this example goes to http://example.com/contextname/home), else it will set an error message and forward the request back to the same JSP page so that the message get displayed by ${error}.
You can if necessary also "hide" the login.jsp in /WEB-INF/login.jsp so that the users can only access it by the servlet. This keeps the URL clean http://example.com/contextname/login. All you need to do is to add a doGet() to the servlet like this:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(and update the same line in doPost() accordingly)
That said, I am not sure if it is just playing around and shooting in the dark, but the code which you posted doesn't look good (such as using compareTo() instead of equals() and digging in the parameternames instead of just using getParameter() and the id and password seems to be declared as servlet instance variables — which is NOT threadsafe). So I would strongly recommend to learn a bit more about basic Java SE API using the Oracle tutorials (check the chapter "Trails Covering the Basics") and how to use JSP/Servlets the right way using those tutorials.
See also:
Our servlets wiki page
Java EE web development, where do I start and what skills do I need?
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
Update: as per the update of your question (which is pretty major, you should not remove parts of your original question, this would make the answers worthless .. rather add the information in a new block) , it turns out that you're unnecessarily setting form's encoding type to multipart/form-data. This will send the request parameters in a different composition than the (default) application/x-www-form-urlencoded which sends the request parameters as a query string (e.g. name1=value1&name2=value2&name3=value3). You only need multipart/form-data whenever you have a <input type="file"> element in the form to upload files which may be non-character data (binary data). This is not the case in your case, so just remove it and it will work as expected. If you ever need to upload files, then you'll have to set the encoding type so and parse the request body yourself. Usually you use the Apache Commons FileUpload there for, but if you're already on fresh new Servlet 3.0 API, then you can just use builtin facilities starting with HttpServletRequest#getPart(). See also this answer for a concrete example: How to upload files to server using JSP/Servlet?
Both GET and POST are used by the browser to request a single resource from the server. Each resource requires a separate GET or POST request.
The GET method is most commonly (and is the default method) used by browsers to retrieve information from servers. When using the GET method the 3rd section of the request packet, which is the request body, remains empty.
The GET method is used in one of two ways:
When no method is specified, that is when you or the browser is requesting a simple resource such as an HTML page, an image, etc.
When a form is submitted, and you choose method=GET on the HTML tag. If the GET method is used with an HTML form, then the data collected through the form is sent to the server by appending a "?" to the end of the URL, and then adding all name=value pairs (name of the html form field and value entered in that field) separated by an "&"
Example:
GET /sultans/shop//form1.jsp?name=Sam%20Sultan&iceCream=vanilla HTTP/1.0 optional headeroptional header<< empty line >>>
The name=value form data will be stored in an environment variable called QUERY_STRING.
This variable will be sent to a processing program (such as JSP, Java servlet, PHP etc.)
The POST method is used when you create an HTML form, and request method=POST as part of the tag. The POST method allows the client to send form data to the server in the request body section of the request (as discussed earlier). The data is encoded and is formatted similar to the GET method, except that the data is sent to the program through the standard input.
Example:
POST /sultans/shop//form1.jsp HTTP/1.0 optional headeroptional header<< empty line >>> name=Sam%20Sultan&iceCream=vanilla
When using the post method, the QUERY_STRING environment variable will be empty.
Advantages/Disadvantages of GET vs. POST
Advantages of the GET method:
Slightly faster
Parameters can be entered via a form or by appending them after the URL
Page can be bookmarked with its parameters
Disadvantages of the GET method:
Can only send 4K worth of data. (You should not use it when using a textarea field)
Parameters are visible at the end of the URL
Advantages of the POST method:
Parameters are not visible at the end of the URL. (Use for sensitive data)
Can send more that 4K worth of data to server
Disadvantages of the POST method:
Can cannot be bookmarked with its data
The servlet container's implementation of HttpServlet.service() method will automatically forward to doGet() or doPost() as necessary, so you shouldn't need to override the service method.
Could it be that you are passing the data through get, not post?
<form method="get" ..>
..
</form>
If you do <form action="identification" > for your html form, data will be passed using 'Get' by default and hence you can catch this using doGet function in your java servlet code. This way data will be passed under the HTML header and hence will be visible in the URL when submitted.
On the other hand if you want to pass data in HTML body, then USE Post: <form action="identification" method="post"> and catch this data in doPost function. This was, data will be passed under the html body and not the html header, and you will not see the data in the URL after submitting the form.
Examples from my html:
<body>
<form action="StartProcessUrl" method="post">
.....
.....
Examples from my java servlet code:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter out = response.getWriter();
String surname = request.getParameter("txtSurname");
String firstname = request.getParameter("txtForename");
String rqNo = request.getParameter("txtRQ6");
String nhsNo = request.getParameter("txtNHSNo");
String attachment1 = request.getParameter("base64textarea1");
String attachment2 = request.getParameter("base64textarea2");
.........
.........

Categories

Resources