JSP

JSP 都会被编译成 Servlet 类,文件位置位于:/work/Catalina/localhost 下。

  • <% %>(代码块),会被编译放到 service 方法中,局部变量
  • <%= %>(表达式语句块),会被编译到 out.println() 中,因此不能有 ; 号
  • <%@ page %>,会被编译到 servlet 类最头部
  • <%! %>(声明语句块),会被编译到 servlet 类下,作为类的属性和方法
  • 其他普通字符串比如 html 会被放入到 out.write() 中

注释

  1. <!-- HTML 注释 -->,浏览器能看到
  2. <%-- JSP 注释--%>,浏览器无法看到

JSP 生命周期

当请求到来时,容器将 .jsp 转为 java 代码并编译为 .class 文件,再加载到容器中,并构造 Servlet 实例调用 jspInit() 方法完成初始化,此时就是一个 Servlet 实例了,每次请求到来只需要分配线程并调用 _jspService() 方法即可,转换和编译只会发生一次。

初始化参数

1、配置 web.xml

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
<servlet-name>indexJSP</servlet-name>
<jsp-file>/index.jsp</jsp-file>
<init-param>
<param-name>username</param-name>
<param-value>ReaJason</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>indexJSP</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

2、在 index.jsp 中重写 jspInit() 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<body>
<%!
public void jspInit(){
ServletConfig sConfig = getServletConfig();
String username = sConfig.getInitParameter("username");
ServletContext ctx = getServletContext();
ctx.setAttribute("username", username);
}
%>

<p>初始化参数为:<%= application.getAttribute("username")%></p>
</body>
</html>

JSP 中的属性

  1. PageContext pageContext
  2. HttpSession session
  3. ServletContext application
  4. ServletConfig config
  5. JspWriter out

PageContext 可以得到任意作用域的属性。

1
2
3
4
5
6
7
8
<%-- 设置页面作用域属性 --%>
<% pageContext.setAttribute("username", "ReaJason") %>

<%-- 设置会话作用域属性 --%>
<% pageContext.setAttribute("username", "ReaJason",PageContext.SESSION_SCOPE) %>

<%-- 设置应用作用域属性 --%>
<% pageContext.setAttribute("username", "ReaJason",PageContext.APPLICATION_SCOPE) %>

关闭脚本元素:

1
2
3
4
5
6
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>

指令

page 指令:定义页面特定的属性,如字符编码、页面响应的内容类型、以及这个页面是否有隐式的会话对象。

1
<% page import="java.util.*" %>
  • import,为 jsp 导入其他类
  • contentType,定义 jsp 响应的 MIME 内容和字符编码,如 text/html; charset=utf-8
  • isELIgnored,是否忽略 EL 表达式
  • isErrorPage,当前页面是否是错误页面
  • errorPage,定义一个资源 URL,如果发生错误则前往那里

taglib 指定:定义 jsp 可以使用的标记库

include 指令:定义在转换时增加到当前页面的文本和代码。

EL 表达式

1
2
3
4
<!-- EL 表达式 -->
${applicationScope.mail}

<%= application.getAttribute("email")%>

禁用 EL 表达式:<%@ page isELIgnored="true" %>

1
2
<!-- EL 表达式使用 [] 取值时,变量可以是Map、bean、List 或数组 -->
${list[0]}

对于对象取值直接 . 获取即可,如 student.name、student.age

EL 隐式对象:

作用域相关:

  • pageScope
  • requestScope
  • sessionScope
  • applicationScope

EL 表达式只能从域对象中获取数据,顺序依次为

pageContext -> request -> session -> application

请求参数:

  • param
  • paramValues

请求头部:

  • header
  • headerValues

其他:

  • cookie
  • initParam:上下文参数
  • pageContext

动作

1、使用 bean

servlet:

1
2
3
4
5
6
7
8
9
10
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
Person p = new Person("ReaJason", 18, 1);
request.setAttribute("p", p);

RequestDispatcher view = request.getRequestDispatcher("result.jsp");
view.forward(request,response);

}

result.jsp:

1
2
3
4
5
6
7
8
<%@ page contentType="text/html; charset=utf-8"%>
<html>
<body>
<jsp:useBean id="p" class="top.reajason.bean.Person" scope="request" />
Person create by servlet: <jsp:getProperty name="p" property="name" />
<%= request.getAttribute("p")%>
</body>
</html>

设置属性:

scope 默认为 page

1
2
3
<jsp:useBean id="person" class="top.reajason.bean.Person" scope="page">
<jsp:setProperty name="person" property="name" value="Fred" />
</jsp:useBean>
1
2
3
4
<!-- 使用 type 标记声明类型,使用 class 标记 new 的类型 -->
<jsp:useBean id="employee" type="top.reajason.bean.Person" class="top.reajason.bean.Employee" scope="page">
<jsp:setProperty name="employee" property="name" value="Fred" />
</jsp:useBean>

使用 jsp:useBean 接参数:

1
2
3
4
<!-- 表单提交时设置的 name 与 javabean 变量名相同 -->
<jsp:useBean id="person" class="top.reajason.bean.Person" scope="page">
<jsp:setProperty name="person" property="*"/>
</jsp:useBean>

2、可重用模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 编译时转换,直接将 Header.jsp 复制到当前页面中 -->
<%@ include file="Header.jsp" %>

<!-- 运行时添加,文件体积更小,性能有开销 -->
<jsp:include page="Header.jsp" />

<!-- 添加参数 -->
<jsp:include page="Header.jsp">
<jsp:param name="subTitle" value="hello World"/>
</jsp:include>

<!-- Header.jsp -->
<p>
${param.subTitle}
</p>

JSTL

安装:需要 jstl 和 standard 两个 lib 文件

1
2
<!-- 引入 -->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

c:out

1
2
<c:out value="<b></b>" default="默认值" />
<c:out value="${EL表达式值替换}" />

c:foreach

1
2
3
4
5
6
7
8
9
<c:foreach var="movie" items="${moveiList}" varStatus="movieLoopCount">
<tr>
<!-- 当前遍历索引 1 开始 -->
<td>${movieLoopCount.count}</td>
</tr>
<tr>
<td>${movie}</td>
</tr>
</c:foreach>

c:if

1
2
3
<c:if test="true">
<jsp:include page="input.jsp" />
</c:if>

JSP
https://reajason.vercel.app/2021/11/22/JavaWebJSP/
作者
ReaJason
发布于
2021年11月22日
许可协议