I know this has been discusses at least a million times here but every servlet was redirecting or flushing the output before calling forward(). I have the same problem but I am not doing anything with the output. My servlet just takes the request parameters and commits to the database and sets an attribute on the request. Then, it forwards the request to a jsp which them displays the attribute. I am using Servlet 3.0 on Tomcat 7. Here is my servlet doPost method followed byt the jsp that this is forwarding to:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doPost(req, resp);
DAOFactory daoFactory = DAOFactory.getFactory();
daoFactory.getCompanyDAO().beginTransaction();
Company company = new Company();
company.setName(req.getParameter("companyName"));
company.setContactEmail(req.getParameter("companyEmail"));
company.setContactPhone(new Long(req.getParameter("companyMobile")));
company.setAddressLine1(req.getParameter("companyAddressLine1"));
company.setAddressLine2(req.getParameter("companyAddressLine2"));
company.setCity(req.getParameter("companyCity"));
company.setZipcode(Integer.parseInt(req.getParameter("companyZip")));
company.setState(req.getParameter("companyState"));
company = daoFactory.getCompanyDAO().save(company);
daoFactory.getCompanyDAO().commitTransaction();
Employee owner = new Employee();
owner.setFirstname(req.getParameter("ownerFirstName"));
owner.setLastname(req.getParameter("ownerLastName"));
owner.setEmail(req.getParameter("ownerEmail"));
owner.setMobileNum(new Long(req.getParameter("ownerCellPhone")));
owner.setZipcode(Integer.parseInt(req.getParameter("ownerZip")));
owner.setRole("Employer");
owner.setCompany(company);
daoFactory.getEmployeeDAO().beginTransaction();
owner = daoFactory.getEmployeeDAO().save(owner);
daoFactory.getEmployeeDAO().commitTransaction();
company.addEmployee(owner);
company.setOwnerId(owner.getId());
daoFactory.getCompanyDAO().beginTransaction();
company = daoFactory.getCompanyDAO().save(company);
daoFactory.getCompanyDAO().commitTransaction();
req.setAttribute("company", company);
RequestDispatcher rd = getServletConfig().getServletContext().getRequestDispatcher("/jsp/companyConfirmation.jsp");
rd.forward(req, resp);
}
JSP:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h3>The Company was saved successfully</h3>
<p>
Company name: ${company.name}
</p>
</body>
</html>
I am sure I may have missed something very trivial. I cannot figure out what it is especially when I am not writing anything to the output before forwarding the request.
PS: I also tried putting a return; statement after the forward but no change.
Thanks!
You should remove the super.doPost(req, resp) method call. The default implementation of doPost method from HTTPServlet returns HTTP 405 status code meaning "Method not supported" and that's the response which has been committed. Therefore, you can not forward your request to other jsp.
This is part of the RequestDispatcher.forward(ServletRequest req, ServletResponse resp) method description: "forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward".
Related
I am trying to build a site that displays report results based on a date range inputted by the user. First I built the front-end "aesthetics" part of it in HTML/CSS/JS using dummy json data to retrieve the results. Now I am trying to eliminate the json and actually integrate it with the backend, which I have no experience with so am struggling a bit.
Right now I have a Java servlet written, and it works alright. I'm writing the ResultSet from the database query by doing response.getWriter().write(""); Now from what I've seen the next step is to display the results by appending to the URL, but the code that formats and displays it properly is just a div currently. What is the proper way to do this/modify the code?
Sorry if this is a badly written question, I'm not totally sure of all the terminology or best practices, although I'm trying to learn.
EDIT: Currently on the html page I have
$('#gen-report').click(function(){
$("#auction-report").fadeIn({ duration: 400 });
}
In the auction-report div is all of my formatting & elements (charts, displays, etc.) Is there a way to make use of this code instead of having to start my jsp page from scratch?
Put parameters in servlet to request, then invoke forward from request.getRequestDispatcher.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("now", LocalDate.now());
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/view/test.jsp");
dispatcher.forward(request, response);
}
Now you have access to params which you put in request. Here jsp:
<%# page language="java" contentType="text/html; charset=windows-1255"
pageEncoding="windows-1255"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1255">
<title>Test</title>
</head>
<body>
<h2>Date</h2>
<%= request.getParameter("now") %>
</body>
</html>
How can we prevent frame injection in Java application?
Like in a Penetration testing,
it is found that if a hacker drafts a demo html page,
and inside that page he has used iframe,
which has the URL of the working application,
he/she can see the data through that URL/request(created in an iframe).
suppose this is the hackers file, test.html:
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head><body>
<iframe id="inner" src="http://hostname:8080/Application_Name/ABC/DEF/SomePage.jsp?ABC=QWERTYL&XYZ=1&CDE=24" width="600" height="400" scrolling="yes">
</iframe>
</body>
</html>
And now the hacker is able to retrieve the data within the application. How to stop this?
This is clickjacking attack: https://www.owasp.org/index.php/Clickjacking
The simpliest way to prevent it is to add header "X-Frame-Options" with value "DENY". This can be done using filter. Register it in your web.xml and use code like this:
#Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException,
ServletException {
HttpServletResponse response = (HttpServletResponse) resp;
response.addHeader("X-Frame-Options", "DENY");
chain.doFilter(req, resp);
}
All modern browsers support this header, but to protect users with legacy browsers you will need also defensive javascript in the UI. More details: https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet
This question already has answers here:
How to call servlet through a JSP page
(6 answers)
Closed 6 years ago.
I want to call a servlet latest_products on load of index.jsp page.This servlet has records in List. I want to pass this List<products> to index.jsp. But I don't want to display the name of servlet in url. Is there any way by which I can do this.
Solution 1
Steps to follow:
use jsp:include to call the Servlet from the JSP that will include the response of the Servlet in the JSP at runtime
set the attribute in the request in Servlet and then simply read it in JSP
Sample code:
JSP:
<body>
<jsp:include page="/latest_products.jsp" />
<c:out value="${message }"></c:out>
</body>
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
}
EDIT
but i don't want to display the name of servlet in url.
Simply define a different and meaningful url-pattern for the Servlet in the web.xml such as as shown below that look like a JSP page but internally it's a Servlet.
web.xml:
<servlet>
<servlet-name>LatestProductsServlet</servlet-name>
<servlet-class>com.x.y.LatestProductsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LatestProductsServlet</servlet-name>
<url-pattern>/latest_products.jsp</url-pattern>
</servlet-mapping>
Solution 2
Steps to follow:
first call to the the Servlet
process the latest products
set the list in the request attribute
forward the request to the JSP where it can be accessed easily in JSP using JSTL
Sample code:
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
RequestDispatcher view=request.getRequestDispatcher("index.jsp");
view.forward(request,response);
}
index.jsp:
<body>
<c:out value="${message }"></c:out>
</body>
hit the URL: scheme://domain:port/latest_products.jsp that will call the Servlet's doGet() method.
(...) but I don't want to display the name of servlet in url.
You don't need to use the Servlet name at all when accessing to a Servlet. In fact, you can create your servlet to point to the desired URL by defining the right URL pattern:
#WebServlet("/index.jsp")
public class LatestProductServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<Product> productList = ...
//all the necessary code to obtain the list of products
//store it as request attribute
request.setAttribute("productList", productLlist);
//forward to the desired view
//this is the real JSP that has the content to display to user
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
}
Then, you will have a folder structure like this
- <root folder>
- WEB-INF
+ index.jsp
+ web.xml
And in WEB-INF/index.jsp:
<!DOCTYPE html>
<html lang="es">
<body>
<!--
Display the data accordingly.
Basic quick start example
-->
<c:forEach items="${productList}" var="product">
${product.name} <br />
</c:forEach>
</body>
</html>
Note that your clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.jsp and will get the desired content. And you don't need to fire two GET requests to retrieve the content for your specific page.
Note that you can go further with this approach: Since the pattern is now defined in servlet, you may choose to not use index.jsp for your clients, but index.html to access to your page. Just change the URL pattern in the Servlet:
#WebServlet("/index.html")
public class LatestProductServlet extends HttpServlet {
//implementation...
}
And the clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.html, which will show the results in WEB-INF/index.jsp. Now both your clients and you will be happy: clients will get their data and you won't show that ugly servlet name in your URL.
Additional
If you have index.jsp as your welcome page in web.xml, this approach won't work because application servlet expects that a real file index.jsp exists. To solve this issue, just create an empty file named index.jsp:
- <root folder>
- index.jsp <-- fake empty file to trick the application server
- WEB-INF
+ index.jsp
+ web.xml
And when accessing to http://<yourWebServer>:<port>/<yourApplication>/, will work as shown above.
Thanks to +Braj, I am able to make an answer using Expression Language. Apparently, this is supposed to be better than jsp scripting/tags.
Servlet -
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ProductList extends HttpServlet {
private static final long serialVersionUID = 1L;
public ProductList() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<String> products = new ArrayList<String>();
products.add("Car");
products.add("Gun");
products.add("Shades");
request.setAttribute("productsList", products);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
JSP -
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:import url="/ProductList" />
<c:set var="myProducts" value="${requestScope.productsList}" />
<h1>List of products from servlet</h1>
<c:forEach var="product" items= "${myProducts}" varStatus="i">
${product}<br>
</c:forEach>
</body>
</html>
I know that response.sendRedirect() destroys the request/response object and new request is sent to the resource. So how come request.getParameter("") fetches me the value if the earlier request/response object has already been destroyed.
NewFile.HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form action ="MyServlet">
<label>Username</label>
<input type="text" name="textbox1"/><br>
<label>Password</label><input type="password" name="textbox2"/>
<input type="submit"/>
</form>
</body>
</html>
Servlet
/**
* Servlet implementation class MyServlet
*/
#WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String user = request.getParameter("textbox1");
String password = request.getParameter("textbox2");
if (user.equals("abc")&&password.equals("123"))
{
response.sendRedirect("NewFile.jsp?name="+user);
}
}
}
Newfile.jsp
<%= "hi there"+request.getParameter("name") %>
I repeated here the comment so you can mark your question as solved by this answer :D
If you are talking about your jsp getting parameter "name"... it's simply because you have put the request directly in the url (NewFile.jsp?name=xuser). If not, I didn't understand your question, please try to be clearer
It is because at very first request, you are getting the parameter, after that you are sending redirect response, if you will do same thing on redirected page or servlet, you will not able to get any thing. In your case, you are sending parameter name with value, so you will be able to get it.
Go to your "NewFile.jsp" page, in that page <%=request.getParameter("name")>.
It will simply get the value you passed in URL("NewFile.jsp?name="+user).
I have written a filter to add some header values to Response object.
The doFilter is setting some header value as shown below
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain filterChain)
throws IOException, ServletException
{
final HttpServletResponse response = (HttpServletResponse) res;
final HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("X-FRAME-OPTIONS", "SAMEORIGIN");
filterChain.doFilter(req, res);
}
Filter mapping is "/*".
I have index.jsp page as welcome page and this is the only page in my application. I am trying to read the header value set in above method.
My index.jsp is
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#page import="java.util.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello world</title>
</head>
<body>
<%
out.println("<br/><br/>XFRAME"+request.getHeader("X-FRAME-OPTIONS"));
%>
<br/>
</body>
</html>
I am getting Null output in the page. I could not get how I got null value if the value is set to "SAMEORIGIN".
XFRAMEnull
can any one help on this.
That's simple, you have added an attribute in the HttpServletResponse headers and expect to read it from the HttpServletRequest headers. That doesn't work that way.
What you need to understand is the HTTP Protocol. The HttpServletRequest is the request coming from the client side to the server while the HttpServletResponse is the response of data and streams coming from the server and translated back to client message (rendered by the browser).
Each headers from either the request/response has information necessary for the server to know what it receives, how to translate the received data and what response to return. Hence why the HttpServletRequest.getHeaders() will almost never be identical to HttpServletResponse.getHeaders() as each of the request/response conforms to the HTTP request/response protocols.
Also, you can never expect to populate a response and magically appear on the request.
I hope this helps.