Overview of JavaServer Pages
JSP (JavaServer Pages) is a technology that allows embedding Java code within HTML pages to generate dynamic web content on the server side.
Basic Structure:
<html>
<head>
<title>Demo</title>
</head>
<body>
<h1>JSP Greeting</h1>
<%
System.out.println("Hello from JSP");
%>
</body>
</html>
Quick Start
Environment Setup
Create a Maven web project and configure the pom.xml to include the necessary dependencies.
Dependencies:
<dependencies>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSP API -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
Basic Coding
Create a file named hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>First JSP</title>
</head>
<body>
<h1>JSP, hello</h1>
<%
System.out.println("hello JSP");
%>
</body>
</html>
Access via: http://localhost:8080/project-name/hello.jsp
How JSP Works
- When a browser requests
hello.jsp, the Tomcat server translates the file into a Servlet source file (e.g.,hello_jsp.java). - The server compiles this Java file into bytecode (
hello_jsp.class). - The container loads the class and executes the
_jspServicemethod to handle the request.
JSP files are essentially Servlets. HTML content is typically handled via out.write() statements within the generated Servlet.
JSP Scripting Elements
Classification
- Scriptlet:
<% ... %>— Code inside is placed directly into the_jspServicemethod. - Expression:
<%= ... %>— Used to output data; equivalent toout.print(...). - Declaration:
<%! ... %>— Defines class-level members (variables or methods) outside the service method.
Examples
Scriptlet:
<%
int count = 10;
System.out.println(count);
%>
Expression:
<%= count %>
Declaration:
<%!
private String appName = "InventorySystem";
%>
Case Study: Displaying Data in a Table
Implementation
Manually writing HTML for every row is inefficient. We use Java code to iterate over a list.
Data Preparation and Rendering:
<%@ page import="com.example.model.Product" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
List<Product> products = new ArrayList<>();
products.add(new Product(1, "Laptop", 1200));
products.add(new Product(2, "Mouse", 25));
products.add(new Product(3, "Keyboard", 75));
%>
<html>
<body>
| ID | Name | Price |
|---|---|---|
| <%= p.getId() %> | <%= p.getName() %> | $<%= p.getPrice() %> |
</body>
</html>
Drawbacks and Evolution
Disadvantages:
- Mixing HTML and Java makes files hard to read and maintain.
- Debugging is difficult because errors point to generated
.javafiles. - High resource consumption and complex environment requirements.
- Poor separation of concerns between designers and developers.
Evolution Path:
- Servlet Only: Hard-coding HTML inside Java Servlets.
- JSP: Separating HTML presentation but still embedding logic.
- MVC with JSP: Using Servlets for logic and JSP for pure viewing.
- Modern Approach: Using HTML + AJAX (Fetching data via JavaScript) + Backend APIs (Spring Boot), effectively replacing JSP.
Expression Language (EL)
EL simplifies accessing data stored in scope objects (page, request, session, application).
Syntax: ${expression}
**Example:**Retrieve a list stored in the request scope inside a Servlet:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
List<Product> list = service.getAll();
req.setAttribute("productList", list);
req.getRequestDispatcher("/view.jsp").forward(req, resp);
}
Display in view.jsp:
<%@ page isELIgnored="false" %>
${productList}
JSTL (JSP Standard Tag Library)
JSTL provides tags to handle common tasks (loops, conditions) without writing Java scriptlets.
Setup
Maven Dependencies:
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
JSP Directive:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Conditional Logic (if)
<c:if test="${user.admin == true}">
<p>Welcome Admin</p>
</c:if>
Iteration (forEach)
<foreach items="${productList}" var="item" varstatus="loop"> | ${loop.count} | ${item.name} | ${item.price} |
|---|---|---|
</foreach>
MVC Pattern and Three-Tier Architecture
MVC Pattern
- Model: Represents business data and logic.
- View: The UI (JSP/HTML).
- Controller: Handles user input, interacts with Model, and selects View.
Three-Tier Architecture
- Presentation Layer (Web): Handles HTTP requests and responses (Servlets/Controllers).
- Business Logic Layer (Service): Contains application logic and rules.
- Persistence Layer (DAO/Mapper): Handles data base operations (MyBatis/JPA).
Relationship
The Controller and View in MVC belong to the Presentation Layer. The Model in MVC spans the Business Logicc Layer and Persistence Layer.
Comprehensive Case: Brand Managemant (CRUD)
Environment Preparation
Entity Class (Brand):
package com.example.entity;
public class Brand {
private Integer id;
private String brandName;
private String companyName;
private Integer ordered;
private String description;
private Integer status; // 0: disabled, 1: enabled
// Constructors, Getters, and Setters
public Brand() {}
public Brand(String brandName, String companyName, Integer ordered, String description, Integer status) {
this.brandName = brandName;
this.companyName = companyName;
this.ordered = ordered;
this.description = description;
this.status = status;
}
// ... getters and setters ...
}
MyBatis Mapper Interface:
package com.example.mapper;
import com.example.entity.Brand;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface BrandMapper {
@Select("SELECT * FROM tb_brand")
@Results({
@Result(column = "brand_name", property = "brandName"),
@Result(column = "company_name", property = "companyName")
})
List<Brand> queryAll();
@Insert("INSERT INTO tb_brand (brand_name, company_name, ordered, description, status) " +
"VALUES (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void create(Brand brand);
@Select("SELECT * FROM tb_brand WHERE id = #{id}")
@Results({
@Result(column = "brand_name", property = "brandName"),
@Result(column = "company_name", property = "companyName")
})
Brand queryById(int id);
@Update("UPDATE tb_brand SET brand_name=#{brandName}, company_name=#{companyName}, " +
"ordered=#{ordered}, description=#{description}, status=#{status} WHERE id=#{id}")
void edit(Brand brand);
@Delete("DELETE FROM tb_brand WHERE id = #{id}")
void remove(int id);
}
Service Layer:
package com.example.service;
import com.example.entity.Brand;
import com.example.mapper.BrandMapper;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class BrandService {
public List<Brand> getAllBrands() {
try (SqlSession session = MyBatisUtil.getFactory().openSession(true)) {
BrandMapper mapper = session.getMapper(BrandMapper.class);
return mapper.queryAll();
}
}
public void addBrand(Brand brand) {
try (SqlSession session = MyBatisUtil.getFactory().openSession(true)) {
BrandMapper mapper = session.getMapper(BrandMapper.class);
mapper.create(brand);
}
}
public Brand getBrand(int id) {
try (SqlSession session = MyBatisUtil.getFactory().openSession(true)) {
BrandMapper mapper = session.getMapper(BrandMapper.class);
return mapper.queryById(id);
}
}
public void updateBrand(Brand brand) {
try (SqlSession session = MyBatisUtil.getFactory().openSession(true)) {
BrandMapper mapper = session.getMapper(BrandMapper.class);
mapper.edit(brand);
}
}
public void deleteBrand(int id) {
try (SqlSession session = MyBatisUtil.getFactory().openSession(true)) {
BrandMapper mapper = session.getMapper(BrandMapper.class);
mapper.remove(id);
}
}
}
Read: Query All Brands
Servlet (SelectAllServlet):
@WebServlet("/list")
public class SelectAllServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BrandService service = new BrandService();
List<Brand> brands = service.getAllBrands();
req.setAttribute("brands", brands);
req.getRequestDispatcher("/brand-list.jsp").forward(req, resp);
}
}
JSP (brand-list.jsp):
<%@ page isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
| ID | Brand | Company | Status | Action |
|---|---|---|---|---|
<foreach items="${brands}" var="b" varstatus="s"> | ${s.count} | ${b.brandName} | ${b.companyName} | <if test="${b.status == 1}">Active</if><if test="${b.status == 0}">Inactive</if> | [Edit](/get?id=${b.id}) [Delete](/delete?id=${b.id}) |
</foreach>
</body>
</html>
Create: Add a Brand
Servlet (AddServlet):
@WebServlet("/add")
public class AddServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Simplified: Assume encoding filter is set up
String bName = req.getParameter("brandName");
String cName = req.getParameter("companyName");
int order = Integer.parseInt(req.getParameter("ordered"));
String desc = req.getParameter("description");
int stat = Integer.parseInt(req.getParameter("status"));
Brand brand = new Brand(bName, cName, order, desc, stat);
new BrandService().addBrand(brand);
resp.sendRedirect("/list");
}
}
JSP (add-brand.jsp):
<form action="/add" method="post">
Brand: <input name="brandName"><br>
Company: <input name="companyName"><br>
Order: <input name="ordered"><br>
Desc: <textarea name="description"></textarea><br>
Status: <input type="radio" name="status" value="1">On <input type="radio" name="status" value="0">Off<br>
<input type="submit" value="Save">
</form>
Update: Modify a Brand
Step 1: Load Data for Editing (Servlet):
@WebServlet("/get")
public class GetServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = Integer.parseInt(req.getParameter("id"));
Brand brand = new BrandService().getBrand(id);
req.setAttribute("brand", brand);
req.getRequestDispatcher("/edit-brand.jsp").forward(req, resp);
}
}
Step 2: Edit Form (edit-brand.jsp):
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<form action="/update" method="post">
<!-- Hidden field to pass the ID -->
<input type="hidden" name="id" value="${brand.id}">
Brand: <input name="brandName" value="${brand.brandName}"><br>
Company: <input name="companyName" value="${brand.companyName}"><br>
Order: <input name="ordered" value="${brand.ordered}"><br>
Desc: <textarea name="description">${brand.description}</textarea><br>
Status:
<input type="radio" name="status" value="1" <c:if test="${brand.status == 1}">checked</c:if>>On
<input type="radio" name="status" value="0" <c:if test="${brand.status == 0}">checked</c:if>>Off<br>
<input type="submit" value="Update">
</form>
Step 3: Process Update (Servlet):
@WebServlet("/update")
public class UpdateServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
int id = Integer.parseInt(req.getParameter("id"));
String bName = req.getParameter("brandName");
String cName = req.getParameter("companyName");
int order = Integer.parseInt(req.getParameter("ordered"));
String desc = req.getParameter("description");
int stat = Integer.parseInt(req.getParameter("status"));
Brand brand = new Brand(bName, cName, order, desc, stat);
brand.setId(id);
new BrandService().updateBrand(brand);
resp.sendRedirect("/list");
}
}
Delete: Remove a Brand
Servlet (DeleteServlet):
@WebServlet("/delete")
public class DeleteServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
int id = Integer.parseInt(req.getParameter("id"));
new BrandService().deleteBrand(id);
resp.sendRedirect("/list");
}
}