You don't. What you do is you call the controller and have if forward to the JSP. You never call the JSPs directly themselves.
So, what you end up with is:
request --- invokes ---> Controller --- forwards to ---> JSP
The Controller can fetch whatever is necessary and populate the request appropriately before called the JSP to render it all.
Addenda -
Here is a simple Servlet, mapped to /MyServlet :
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MemberDAO dao = DAOFactory.getMemberDAO();
List<Member> members = dao.getMembers();
request.setAttribute("members", members);
RequestDispatcher rd = getServletContext().getRequestDispatcher("/WEB-INF/jsp/members.jsp");
rd.forward(request, response);
}
}
And here is an associated JSP placed at /WEB-INF/jsp/members.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ 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=UTF-8">
<title>Members List</title>
</head>
<body>
<h1>Members List</h1>
<table>
<tr>
<td>Member ID</td>
<td>First Name</td>
<td>Last Name</td>
</tr>
<c:forEach items="${members}" var="member">
<tr>
<td>${member.id}</td>
<td>${member.firstName}</td>
<td>${member.lastName}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
In your browser, you hit: http://yourhost/yourapp/MyServlet
The servlet, acting as a controller, takes the request, acts on it (in this case getting a list of all of the members from the database using a simple DAO pattern), and then puts the results in to the request with the tag "members" (the request.setAttribute("members", members)
does this).
One the request is properly populated with interesting information, the servlet forward to the JSP.
Note in this case the JSP is located below the WEB-INF directory. JSPs located within WEB-INF are NOT accessible at all from the browser. So a request to http://yourhost/yourapp/WEB-INF/jsp/members.jsp will simply fail.
But they are accessible internally.
So, the Servlet forwards to members.jsp, and members.jsp renders, locating the members
value from the request (${members} in the JSTL c:forEach tag), and the c:forEach iterates across that list, populating the member
variable, and from there filling out the rows in the table.
This is a classic "controller first" pattern which keeps the JSP out of the way. It also helps maintain that the JSPs only live in the View layer of MVC. In this simple example, Member and the List is the model, the Servlet in the Controller, and the JSP is the view.