2.1. Environment & Project Setup
-
Java EE Web Server/Container: A runtime environment (e.g., Apache Tomcat, Jetty, GlassFish) that implements Java EE (Jakarta EE) specifications for Servlets, JSP, etc.
-
Standard Web App Directory Structure:
| Directory/File | Purpose | | :--- | :--- | |
WEB-INF/| Secure directory not directly accessible via URL. | |WEB-INF/web.xml| Deployment Descriptor (optional with annotations). | |WEB-INF/classes/| Compiled.classfiles (Servlets, JavaBeans). | |WEB-INF/lib/| JAR files (e.g.,jstl.jar, database drivers). | |.jsp,.html,.css,.js| Static and dynamic web resources (placed at root). | -
Dynamic Web Project in IDE: IDE-specific project type that auto-generates the above structure and facilitates deployment.
-
Deployment Process: Build project → IDE/Server tool copies app to server's
webapps/directory → Server unpacks/loads app → Access viahttp://localhost:8080/<context-path>.
[!TIP] The context path is the app's root URL name (often the project/WAR name).
WEB-INFis crucial for security; clients cannot request files inside it directly.
2.2. Servlet Fundamentals
-
Servlet: A Java class that extends
HttpServletand handles HTTP requests/responses on the server side. -
Lifecycle (3 Phases):
-
init(): Called once by container after servlet instantiation. For one-time setup. -
service(): Called for each request. Container callsdoGet()/doPost()etc. based on HTTP method. -
destroy(): Called once before servlet removal. For cleanup.
graph LR A[Client Request] --> B[Servlet Instantiation]; B --> C[init()]; C --> D[service()]; D --> E[doGet/doPost]; E --> F[Response]; F --> D; G[Container Shutdown] --> H[destroy()]; -
-
Key API Interfaces:
-
HttpServletRequest: Encapsulates client request (parameters, headers, session). -
HttpServletResponse: Encapsulates server response (content type, writer, headers).
-
-
Writing a Basic Servlet:
@WebServlet("/hello") // Annotation (Servlet 3.0+) public class HelloServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>Hello World</h1>"); } } -
Deployment Descriptor (
web.xml): XML file inWEB-INF/for declarative config (used when annotations are insufficient or for ordering).<servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.example.HelloServlet</servlet-class> <init-param> <param-name>user</param-name> <param-value>admin</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> -
Annotations:
@WebServlet(urlPatterns={"/url1", "/url2"}),@WebInitParam(name="param", value="value").
[!TIP]
doGet()for fetching data (idempotent),doPost()for form submissions/data modification. Never overrideservice()unless for advanced needs.
2.3. Handling Client Requests & Server Responses
-
Reading Request Data:
-
Query/Form Parameters:
String value = request.getParameter("name");(works for both GET query string & POST form data). -
Request Headers:
String agent = request.getHeader("User-Agent"); -
Path Parameters: From
@WebServlet("/user/*")→request.getPathInfo().
-
-
Generating Responses:
-
response.setContentType("text/html; charset=UTF-8");(Always set charset!) -
PrintWriter out = response.getWriter();→out.println(...).
-
-
Request Dispatching (Server-Side):
-
RequestDispatcher rd = request.getRequestDispatcher("target.jsp"); -
rd.forward(request, response);→ Forwards request/response objects. Client URL unchanged. Used for MVC (Servlet as Controller → JSP as View). -
rd.include(request, response);→ Includes content of target in current response. Used for templates (header/footer).
-
-
Client-Side Redirect:
response.sendRedirect("http://example.com/page");→ Sends 302 status. New request created. Client URL changes. Used for PRG pattern (Post/Redirect/Get).
| Aspect | forward() |
sendRedirect() |
|---|---|---|
| Who handles? | Server (internal) | Client (browser) |
| Request Object | Same object passed | New request created |
| URL in Browser | Unchanged | Changes to new URL |
| Use Case | MVC (Controller → View) | PRG pattern, redirect to external site |
[!TIP] PRG Pattern: After
doPost()(form submission), usesendRedirect()to adoGet()page to prevent duplicate form submission on refresh.
2.4. JavaServer Pages (JSP) Fundamentals
-
JSP Lifecycle:
-
Translation:
.jsp→.java(Servlet source). -
Compilation:
.java→.class(Servlet bytecode). -
Execution: Servlet
service()method handles requests.
-
-
JSP Elements:
| Element | Syntax | Purpose | Note | | :--- | :--- | :--- | :--- | | Scriptlet |
<% Java code %>| Embed Java logic. | Discouraged (breaks MVC). | | Expression |<%= expression %>| Evaluate & print result. | Auto-converts to string. | | Declaration |<%! declaration %>| Define class-level members. | Rarely used. | | Directive |<%@ directive %>| Page-level config. |page,include,taglib. | | Action |<jsp:action>| Use JavaBean/control flow. |useBean,setProperty,include,forward. | -
Key Directives:
-
<%@ page contentType="text/html;charset=UTF-8" %> -
<%@ include file="header.jsp" %>→ Static include (at translation time). -
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>→ Import JSTL.
-
-
Implicit Objects (9):
request,response,session,application,out,pageContext,config,page,exception(only in error pages).
[!TIP] Avoid Scriptlets! Use JSTL & EL for view logic. JSP should be view-only in MVC.
2.5. JSP Expression Language (EL) & JSTL
-
Expression Language (EL):
${expression}. Accesses scoped attributes (pageScope,requestScope,sessionScope,applicationScope).-
Implicit Objects:
${param}`, `${paramValues},${header}`, `${cookie},${initParam}`, `${pageContext}. -
Operators:
.,[],?,empty,==,!=,<,>,&&,||,+,-,*,/,%. -
Example:
${user.name}` or `${user['name']}(ifuseris in any scope).
-
-
JSTL (JavaServer Pages Standard Tag Library): Must add JARs (
jstl.jar,standard.jar) toWEB-INF/lib/.-
Core Tags (
c:):<c:out value="${user.name}" default="N/A"/> <c:set var="total" value="${100 * 2}"/> <c:remove var="temp"/> <c:if test="${user.age > 18}">Adult</c:if> <c:choose> <c:when test="${score >= 90}">A</c:when> <c:otherwise>B</c:otherwise> </c:choose> <c:forEach var="item" items="$$\displaystyle {list}"> $${item}</c:forEach> <c:forTokens items="a,b,c" delims="," var="token"/> -
Formatting Tags (
fmt:):<fmt:formatNumber value="$$\displaystyle {price}" type="currency"/>`, `<fmt:formatDate value=" $${date}" pattern="dd/MM/yyyy"/>. -
SQL Tags (
sql:): For learning/labs only (not production).<sql:query>,<sql:update>.
-
-
Setup:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>.
[!TIP] EL automatically calls getter methods (e.g.,
${user.name}→user.getName()). JSTL replaces scriptlets. Use<c:forEach>instead of scriptlet loops.
2.6. Session Management
-
Why? HTTP is stateless. Session tracks a user across multiple requests.
-
Techniques:
| Technique | How it Works | Pros | Cons | | :--- | :--- | :--- | :--- | | Cookies |
response.addCookie(new Cookie("id", "123"));| Simple, persistent. | User can disable, size limit (~4KB). | | URL Rewriting |response.encodeURL("page.jsp")→ appends;jsessionid=...| Works when cookies disabled. | Ugly URLs, must encode every link. | | Hidden Fields |<input type="hidden" name="sessionId" value="...">| Simple for forms. | Only works for POST, not for links/resources. | | HttpSession |HttpSession session = request.getSession(); session.setAttribute("user", userObj);| Most common. Server-side, no client exposure. | Uses memory, requires session tracking (cookies/URL). | -
HttpSession API:
-
request.getSession()→ creates if doesn't exist. -
request.getSession(false)→ returns null if no session. -
session.setAttribute(String name, Object obj) -
session.getAttribute(String name) -
session.invalidate()→ kill session (logout).
-
-
Session Timeout: Configured in
web.xml(minutes) or programmatically.<session-config> <session-timeout>30</session-timeout> <!-- 30 minutes --> </session-config>
[!TIP] Default session tracking uses Cookies. If cookies disabled, container falls back to URL rewriting only if you use
response.encodeURL()on all links/forms. Never store large objects in session.
2.7. Database Connectivity with JDBC in Web Apps
-
Standard JDBC Workflow (in Servlet/JSP):
-
Load Driver:
Class.forName("com.mysql.cj.jdbc.Driver");(Optional for JDBC 4.0+ if JAR hasMETA-INF/services). -
Get Connection:
-
DriverManager (Not Recommended):
DriverManager.getConnection(url, user, pass); -
DataSource via JNDI (Recommended - Connection Pooling):
Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyDB"); Connection conn = ds.getConnection();
-
-
Create Statement: Use
PreparedStatementfor user input (prevents SQL injection).PreparedStatement pstmt = conn.prepareStatement("INSERT INTO users(name) VALUES(?)"); pstmt.setString(1, userName); -
Execute:
pstmt.executeUpdate()(INSERT/UPDATE/DELETE) orpstmt.executeQuery()(SELECT →ResultSet). -
Process ResultSet:
while(rs.next()) { String name = rs.getString("name"); } -
Close Resources (CRITICAL): Use try-with-resources (Java 7+).
try (Connection conn = ds.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery()) { // process rs } catch (SQLException e) { e.printStackTrace(); }
-
-
Configuring DataSource in Tomcat (
context.xml):<Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.cj.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" username="root" password="password" maxTotal="20" maxIdle="10"/> -
Connection Pooling: Reuses database connections, improves performance, avoids overhead of creating new connection per request.
[!TIP] ALWAYS use
PreparedStatement, neverStatementwith user input. ALWAYS closeConnection,Statement,ResultSetin reverse order. Use try-with-resources.
2.8. Error Handling & Page Organization
-
Error Page in
web.xml:<error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/notfound.jsp</location> </error-page> -
JSP Error Page:
<%@ page isErrorPage="true" %>→ grants access to implicit objectexception(Throwable).<h1>Error: <%= exception.getMessage() %></h1> -
Template Design Pattern (Using
include):-
header.jsp,footer.jsp. -
In main JSP:
<%@ include file="header.jsp" %>(static) or<jsp:include page="header.jsp" />(dynamic, can pass params). -
Static include (
<%@ include %>) merges files at translation time (better performance). Dynamic include (<jsp:include>) includes at request time (flexible).
-
[!TIP] Define a generic error page for
java.lang.Throwableas a catch-all. Useexception.printStackTrace()in logs, but show user-friendly message.
2.9. Filters & Listeners
-
Servlet Filter:
-
Interface:
javax.servlet.Filter→init(FilterConfig),doFilter(ServletRequest, ServletResponse, FilterChain),destroy(). -
FilterChain.doFilter(): Must call to pass request to next filter/target resource. -
Uses: Authentication, Logging, Compression, Character Encoding (e.g.,
request.setCharacterEncoding("UTF-8")). -
Mapping:
@WebFilter("/admin/*")or inweb.xml:<filter> <filter-name>AuthFilter</filter-name> <filter-class>com.example.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>AuthFilter</filter-name> <url-pattern>/admin/*</url-pattern> </filter-mapping>
-
-
Servlet Listeners:
-
ServletContextListener:contextInitialized(),contextDestroyed()→ App startup/shutdown (e.g., load DB connection pool). -
HttpSessionListener:sessionCreated(),sessionDestroyed()→ Track active sessions. -
ServletRequestListener:requestInitialized(),requestDestroyed()→ Per-request logging. -
Config:
@WebListenerorweb.xml:<listener> <listener-class>com.example.AppContextListener</listener-class> </listener>
-
[!TIP] Filter Chain Order: Defined by
<filter-mapping>order inweb.xml. First filter mapped is invoked first. Use for cross-cutting concerns.
2.10. Advanced Topics & Best Practices
-
Thread Safety in Servlets:
-
Servlets are multithreaded (single instance, multiple threads).
-
Never use instance variables for request-specific data (use local variables or request/session attributes).
-
Synchronization only if absolutely necessary (hurts performance). Prefer stateless design.
-
-
MVC (Model-View-Controller):
-
Model: JavaBeans/POJOs (business logic, data). DAO layer for DB.
-
View: JSP (with JSTL/EL only). No Java code.
-
Controller: Servlet. Processes request, calls Model, stores result in request/session, forwards to JSP.
-
Flow:
Client → Servlet (Controller) → DAO (Model) → request.setAttribute() → forward → JSP (View).
-
-
File Upload (Servlet 3.0+
PartAPI):@MultipartConfig public class UploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Part filePart = request.getPart("file"); // <input type="file" name="file"> String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); filePart.write("C:/uploads/" + fileName); // Save to disk } }- Form must have
enctype="multipart/form-data".
- Form must have
-
File Download:
File file = new File("path/to/file.pdf"); response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=\"download.pdf\""); Files.copy(file.toPath(), response.getOutputStream()); -
Internationalization (i18n):
-
ResourceBundle:
ResourceBundle.getBundle("Messages", request.getLocale()). -
Store locale-specific strings in
Messages_en.properties,Messages_hi.properties. -
In JSP:
<fmt:message key="welcome.msg"/>(with JSTL formatting taglib).
-
[!TIP] MVC is mandatory for maintainable apps. Servlets = Controllers. JSP = Views (EL/JSTL only). DAO pattern separates DB logic.
2.11. Deployment & Web Application Archive (WAR)
-
WAR (Web Application Archive): Standard packaging format. A
.warfile is a ZIP with specific structure:myapp.war (unzipped) ├── META-INF/ ├── WEB-INF/ │ ├── web.xml │ ├── classes/ (compiled .class files) │ └── lib/ (dependency JARs) ├── index.jsp ├── css/ └── js/ -
Creating WAR:
-
IDE: Export → WAR file.
-
Command Line (in project root):
jar -cvf myapp.war *(ensureWEB-INFstructure is correct).
-
-
Deploying WAR:
-
Copy
myapp.warto Tomcat'swebapps/directory. -
Tomcat auto-explodes (unzips) and deploys.
-
Access via:
http://localhost:8080/myapp/(context path = WAR filename).
-
-
Context Path: Can be renamed by renaming WAR file (e.g.,
ROOT.warfor root context) or via<Context path="/custom" docBase="myapp"/>inserver.xmlorcontext.xml.
[!TIP] Always test WAR deployment on a clean server. The
WEB-INF/classesandWEB-INF/libmust contain all required classes/JARs. No external dependencies allowed at runtime.