这一次练习对JSP和Servlet进行了补充学习
- 1.JSP的本质:
- 2.include指令的作用:
- 3.EL表达式语言与JSTL:
- 关于EL表达式:
- (1)EL表达式用于取参数值与参数值的设定:
- (2)EL表达式的本质:
- (3)开启EL表达式:
- 关于JSTL:
- 一般标签:
- 自闭合标签:
- 4.JavaBean:
- 5.JavaDao:
- 6.HTTP协议响应代码:
- 6.JSP作用域:
- 7.HttpServletRequest和HttpServletResponse
- 8.中文编码问题:
这一次练习根据 how2j对JSP和Servlet进行了补充学习。
1.JSP的本质:
JSP文件虽然是Java、html、jsp标签的合体,但它在运行时会被转换成"文件名_jsp.java"的一个servlet,借用how2j上的图片来说明:
- 把 hello.jsp转译为hello_jsp.jav
- hello_jsp.java 位于 d:\tomcat\work\Catalina\localhost_\org\apache\jsp
- hello_jsp.java是一个servlet
- 把hello_jsp.java 编译为hello_jsp.class
- 执行hello_jsp,生成html
- 通过http协议把html 响应返回给浏览器
2.include指令的作用:
在第一次学习这个指令的时候,只在想着这个指令是什么而在很大程度上忽略了它的作用。既然include指令将一个页面的jsp代码插入到另一个页面,那么我们可以将需要多次使用的页面元素,如页眉、页尾等,写到单独的jsp页面中,在以后使用时,通过include指令插入即可。
页尾元素代码:
插入页尾元素:
<%@include file ="footer.jsp" %>
页尾元素实现效果:
3.EL表达式语言与JSTL:
EL表达式常常与JSTL配合起来使用
关于EL表达式:
EL表达式的格式:
${参数}
(1)EL表达式用于取参数值与参数值的设定:
- 在一个普通的JSP页面中,开启EL支持后使用
"${参数}"
就可以向网页取出并输出参数的值,或者配合JSTL标签,设定JSTL标签定义变量的值,具体例子见下文。
(2)EL表达式的本质:
EL表达式`${参数}`本质上还是一个JSP表达式,可以在 JSP 页面中用于获取变量值、执行函数等操作。而 `<%=参数 %>` 是一种 JSP 脚本表达式,可以在 JSP 页面中用于输出文本内容,但不支持 JSP EL(Expression Language)表达式的语法。也就是说用JSTL声明并赋值的参数是不可以用 `<%=参数 %>`调用的。值得一提的是,在Java片段中声明的变量,使用EL表达式也调用不了。但是,可以通过将这些变量存储在 request、session 或 application 等范围中,然后通过 EL 表达式获取对应范围中的变量值来实现在 JSP 页面中访问这些变量。
<%
String name = "Tom";
<!--无下面这行代码,网页不会错误,但name不会显示-->
request.setAttribute("name", name);
%>
<p>My name is ${requestScope.name}.</p>
(3)开启EL表达式:
不同版本的tomcat是否默认开启对EL表达式的支持,是不一定的(Tomcat7.0默认开启)。我们可以通过在<%@page 标签里加上isELIgnored="false"
来开启EL表达式。
关于JSTL:
与HTML标签相似,JSTL标签分为一般标签和自闭和标签:
在使用JSTL标签库前,需要使用
<%@ taglib uri="http://java.sun.com/jsp/jstl/库名" prefix="引用前缀名"%>
来引入标准库中的标签库,我们暂时以(可自定义)
以c表示访问标签库core的前缀
以fmx表示访问标签库fmx的前缀
一般标签:
一般标签是指需要使用开始标签和结束标签才能实现其功能的标签
(1)if else:
在正常的Java片段中的if-else的条件判断语句写在大括号中(可以使用逻辑操作符连接)
<c:if bool = " ${ hp < 5} ">
这个英雄状态不好
</c:if>
(2)choose、when和otherwise:
<c:choose>、<c:when> 和 <c:otherwise> 标签组合起来可以实现类似于 switch 语句的功能
<c:choose>
<c:when test="${dayOfWeek == 1}">
<p>星期日</p>
</c:when>
<c:when test="${dayOfWeek == 2}">
<p>星期一</p>
</c:when>
<c:when test="${dayOfWeek == 3}">
<p>星期二</p>
</c:when>
<c:otherwise>
<p>其他日</p>
</c:otherwise>
</c:choose>
(3)forEach:
<c:forEach> 标签用于迭代集合、数组或者其他可迭代对象中的元素。
<%
List<String> heros = new ArrayList<String>();
heros.add("塔姆");
heros.add("艾克");
heros.add("巴德");
heros.add("雷克赛");
heros.add("卡莉丝塔");
request.setAttribute("heros",heros);
%>
<!-- 使用jsp中的for循环来遍历List -->
<table width="200px" align="center" border="1" cellspacing="0">
<tr>
<td>编号</td>
<td>英雄</td>
</tr>
<%
int i =0;
for (String hero : heros) {
i++;
%>
<tr>
<td><%=i%></td>
<td><%=hero%></td>
</tr>
<%}%>
</table>
<br>
<!-- 使用JSTL中的c:forEach 循环来遍历List -->
<table width="200px" align="center" border="1" cellspacing="0">
<tr>
<td>编号</td>
<td>英雄</td>
</tr>
<c:forEach items="${heros}" var="hero" varStatus="st" >
<tr>
<td><c:out value="${st.count}" /></td>
<td><c:out value="${hero}" /></td>
</tr>
</c:forEach>
</table>
(4)forTokens:
专门用于字符串拆分,并且可以指定多个分隔符:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:set var="heros" value="塔姆,艾克;巴德|雷克赛!卡莉丝塔" />
<c:forTokens items="${heros}" delims=":;|!" var="hero">
<c:out value="${hero}" /> <br />
</c:forTokens
自闭合标签:
(1)set
set标签用于将一个值赋给指定的变量,供模板中其他部分使用
<c:set var="name" value="Tom" />
<h1>${name}</h1>
(2)out
用来输出变量的一个标签
<c:set var="name" value="${'gareen'}" scope="request" />
通过标签获取name: <c:out value="${name}" />
其实也可以使用
${name}
直接向网页输出。
(3)remove
通过remove标签可以从作用域中移除一个变量或属性。
<c:set var="name" value="Tom" />
<c:set var="age" value="20" />
<c:remove var="name" />
<p>${name}</p> <!-- 这里输出的结果是空值,因为name变量已经被移除了 -->
(4)formatDate:
该标签用于格式化输出日期:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<%
Date now = new Date();
pageContext.setAttribute("now",now);
%>
完整日期: <fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/><br>
完整时间: <fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/><br>
常见格式: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>
通过改变pattern中参数得组合可以输出不同格式得日期时间。
(5)formatNumber:
formatNumber用于格式化输出数字:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix='fmt' %>
<c:set var="money" value="888.8" />
<c:set var="pi" value="3.1415926" />
最少两个小数点:
<fmt:formatNumber type="number" value="${money}" minFractionDigits="2"/>
<br>
最多两个小数点:
<fmt:formatNumber type="number" value="${pi}" maxFractionDigits="2" />
4.JavaBean:
JavaBean指的是一种遵守特定规则的Java类,用于封装一组相关的数据和逻辑,通常包括了一个无参构造函数和通过get/set方法来获取和设置数据的一组属性。它可以被用于在JSP页面和Java程序之间传递和存储数据。
以下是一个JavaBean的实例对象:
package bean;
public class Hero {
public int id;
public String name;
public float hp;
public int damage;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getHp() {
return hp;
}
public void setHp(float hp) {
this.hp = hp;
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
}
通常,JavaBean有以下标准:
1.使用public修饰符定义类,使用一个不带参的构造函数。
2.对应每个属性都有public的getter/setter方法。
3.getter/setter方法必须遵循JavaBeans命名规范,即get/set后跟着属性名的首字母大写版本,例如:getName()和setName()。
4.如果有属性是boolean,那么就对应is和setter方法。
5.可选地,JavaBean还可以实现Serializable接口,用于支持JavaBean实例的持久化。
5.JavaDao:
JavaDao(Data Access Object,数据访问对象)是使用Java语言编写的一种设计模式,用于将数据访问逻辑与业务逻辑分离,以提高代码的可维护性和可重用性。 简单来说,Java DAO 是表示数据访问层的类和接口的集合,它负责处理与数据库相互作用的所有代码。典型的 Java DAO 通常包含 CRUD(Create,Read,Update,Delete)操作,以及其他特定的数据访问逻辑。
写一个JavaDao通常有以下步骤:
(1)先写一个接口用于规范实现该接口必须有哪些方法:
public interface UserDao {
public User findUserById(int id);
public List<User> findAllUsers();
public void insertUser(User user);
public void deleteUser(int id);
public void updateUser(User user);
}
(2)再写一个具体的JavaDao:
public class UserDaoImpl implements UserDao {
// JDBC连接、预编译语句等的常量定义
// ...
@Override
public User findUserById(int id) {
// 使用JDBC访问数据库获取用户信息的代码
// ...
return user;
}
@Override
public List<User> findAllUsers() {
// 使用JDBC访问数据库获取所有用户信息的代码
// ...
return userList;
}
@Override
public void insertUser(User user) {
// 使用JDBC访问数据库将用户信息插入到users表中的代码
// ...
}
@Override
public void deleteUser(int id) {
// 使用JDBC访问数据库将用户信息从users表中删除的代码
// ...
}
@Override
public void updateUser(User user) {
// 使用JDBC访问数据库更新用户信息的代码
// ...
}
}
6.HTTP协议响应代码:
HTTP协议响应代码how2j写得挺有意思的
HTTP协议响应代码的作用是告知客户端请求的处理结果。客户端发送HTTP请求到服务器,服务器根据请求的内容和状态进行处理,并通过响应代码告知客户端请求的处理结果。响应代码提供了一种标准化的方式,使得客户端能够根据不同的响应代码来采取相应的操作,例如显示请求结果、进行重定向、处理错误等。
以下是常见的HTTP协议响应代码的种类及其含义:
1xx(信息性状态码):
- 100 Continue:服务器已收到请求的初始部分,并且客户端应继续发送其余部分。
- 101 Switching Protocols:服务器已理解并接受客户端的请求,将切换到协议升级的新协议。
2xx(成功状态码):
- 200 OK:请求成功,服务器正常处理请求并返回所需的数据。
- 201 Created:请求已成功处理,并创建了新的资源。
- 204 No Content:请求成功处理,但没有返回任何内容。
3xx(重定向状态码):
- 301 Moved Permanently:请求的资源已永久移动到新位置。
- 302 Found:请求的资源暂时移动到其他位置。
- 304 Not Modified:客户端可以使用缓存的版本,无需从服务器重新获取。
4xx(客户端错误状态码):
- 400 Bad Request:服务器无法理解请求,可能是请求语法有误。
- 401 Unauthorized:请求需要身份验证。
- 403 Forbidden:服务器拒绝请求,没有权限访问请求的资源。
- 404 Not Found:请求的资源不存在。
5xx(服务器错误状态码):
- 500 Internal Server Error:服务器在处理请求时遇到了错误。
- 502 Bad Gateway:服务器作为网关或代理,从上游服务器接收到无效的响应。
- 503 Service Unavailable:服务器暂时无法处理请求,通常是由于过载或维护。
6.JSP作用域:
JSP作用域是指在JSP页面中定义的变量在不同的范围内可见的能力。JSP作用域分为四种:page、request、session和application。
page作用域:变量仅在当前JSP页面中可见。在页面中定义的变量只能在当前页面中使用。
request作用域:变量在同一个HTTP请求中可见。在一个JSP页面中设置的变量可以在同一个请求中的其他JSP页面中使用。
session作用域:变量在同一个HTTP会话中可见。在一个JSP页面中设置的变量可以在同一个会话中的其他JSP页面中使用。
application作用域:变量在整个Web应用程序中可见。在一个JSP页面中设置的变量可以在整个应用程序的其他JSP页面中使用。
举一个简单的例子:
<%@ page language="java" %>
<html>
<head>
<title>JSP作用域示例</title>
</head>
<body>
<%-- page作用域 --%>
<%
String name = "John";
pageContext.setAttribute("name", name);
%>
<h1>Page作用域变量: <%= pageContext.getAttribute("name") %></h1>
<%-- request作用域 --%>
<%
String age = "25";
request.setAttribute("age", age);
%>
<h1>Request作用域变量: <%= request.getAttribute("age") %></h1>
<%-- session作用域 --%>
<%
String email = "john@example.com";
session.setAttribute("email", email);
%>
<h1>Session作用域变量: <%= session.getAttribute("email") %></h1>
<%-- application作用域 --%>
<%
String phone = "123-456-7890";
application.setAttribute("phone", phone);
%>
<h1>Application作用域变量: <%= application.getAttribute("phone") %></h1>
</body>
</html>
在这个示例中,我们定义了四个不同作用域的变量,分别是page、request、session和application。在JSP页面中,我们使用pageContext、request、session和application对象来设置和获取这些变量。在页面上,我们展示了每个作用域的变量值。
7.HttpServletRequest和HttpServletResponse
在Java Web开发中,HttpServletRequest和HttpServletResponse是两个非常重要的对象。
HttpServletRequest
HttpServletRequest对象代表了一个HTTP请求,包含了客户端发送给服务器的所有信息。它提供了许多方法来获取请求的信息,例如URL、请求参数、请求头、Session、Cookie等等。HttpServletRequest可以被用于处理用户提交的表单数据,或者读取客户端上传的文件。
下面是一个简单的代码示例,演示了如何使用HttpServletRequest对象:
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name"); // 获取请求参数
if (name == null || name.isEmpty()) {
name = "World";
}
String message = "Hello, " + name + "!";
request.setAttribute("message", message); // 设置请求属性
RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/views/hello.jsp");
dispatcher.forward(request, response); // 转发请求
}
}
在这个示例中,我们定义了一个Servlet,它通过HttpServletRequest获取了请求参数name
,如果没有提供则默认为World
。然后我们通过setAttribute()
方法将一个消息存储到请求属性中,并使用RequestDispatcher
将请求转发到一个JSP页面。
HttpServletResponse
HttpServletResponse对象代表了一个HTTP响应,包括了要发送给客户端的所有内容。它提供了许多方法来设置响应的状态码、响应头、Cookie、输出流等等。HttpServletResponse可以被用于返回文本、HTML、JSON、XML等各种类型的内容。
下面是一个简单的代码示例,演示了如何使用HttpServletResponse对象:
@WebServlet("/hello")
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("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}
在这个示例中,我们定义了一个Servlet,它通过setContentType()
方法设置了响应类型为HTML。然后我们通过getWriter()
方法获取输出流,并使用它输出了一些HTML内容。
总之,HttpServletRequest和HttpServletResponse是Java Web开发中非常重要的两个对象。它们分别代表了HTTP请求和响应,提供了许多方法来处理和生成Web页面。
8.中文编码问题:
见博客Web应用技术(第八周/第5次练习/2h)。