JSP基本使用
什么是jsp
JSP 全名为 Java Server Pages,即 java 服务器页面,是一种动态网页开发技术。它使用 JSP 元素在HTML 网页中插入 Java 代码,从而形成后缀名为.jsp 的 JSP 文件。JSP 元素通常以<%开头,以%>结束。
JSP 是一种 Java servlet,主要用于实现 Java web 应用程序的用户界面部分。网页开发者们通过结合HTML 代码、XHTML 代码、XML 元素以及嵌入 JSP 操作和命令来编写 JSP。JSP 通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP 元素有多种功能,比如访问数据库、记录用户选择信息、访问 JavaBean 组件等,还可以在不同的
网页中传递控制信息和共享信息。
为什么使用JSP
1、性能更加优越,因为 JSP 可以直接在 HTML 网页中动态嵌入元素而不需要单独引用 CGI 文件。服务器调用的是已经编译好的 JSP 文件,而不像 CGI/Perl 那样必须先载入解释器和目标脚本。
2、JSP 基于 Java Servlet API,因此,JSP 拥有各种强大的企业级 Java API,包括 JDBC,JNDI,EJB,JAXP 等等。
3、JSP 页面可以与处理业务逻辑的 servlets 一起使用,这种模式被 Java servlet 模板引擎所支持。最后,JSP 是 Java EE 不可或缺的一部分,是一个完整的企业级应用平台。这意味着JSP 可以用最简单的方式来实现最复杂的应用。
JSP的优势
1、与 ASP 相比:JSP 有两大优势。首先,动态部分用 Java 编写,而不是 VB 或其他MS 专用语言,所以更加强大与易用。第二点就是 JSP 易于移植到非 MS 平台上。
2、与纯 Servlet 相比:JSP 可以很方便的编写或者修改 HTML 网页而不用去面对大量的 println 语句。
3、与 JavaScript 相比:虽然 JavaScript 可以在客户端动态生成 HTML,但是必须使用 A JAX 与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。
4、与静态 HTML 相比:静态 HTML 不包含动态信息。
JSP的结构
在一个 jsp 页面上,既可以包含静态 HTML 代码,也可以包含 Java 代码。
JSP 处理过程
1、当访问JSP,tomcat加载jsp
2、使用模板引擎进行翻译: 默认jsp中内容都当做字符串,使用IO流输出到客户端.被<%%>包裹的内容当做Java代码单独处理.
3、将翻译后java文件,进行编译,产生class文件
4、 tomcat将编译后的文件加载JVM中进行执行.
注意:
1、JSP只有第一次访问时会进行翻译.
2、由于JSP是由一次访问时进行翻译,容易出现缓存问题.所以一般项目发布时,建议先备份项目,清理缓存,发布新项目.
JSP9大内置的对象(9大隐式对象)
为什么在JSP页面,可以直接使用request.getParamter("name"),注意,getParamter是一个方法,被request调用了.说明request是对象.但是我们没有创建request对象,但是可以直接使用.
由于jsp中书写所有代码,在翻译后,都在_jspService方法中,而该方法,都默认有:
HttpServletRequest request 请求对象
HttpServletResponse response 响应对象
PageContext pageContext 当前页面上下文对象
HttpSession session 会话对象(每次对话)
ServletContext application 应用对象(表示当前应用) 全局只有一个
ServletConfig config 配置对象
spWriter out 输出对象
java.lang.Object page 当前类对象
Throwable exception 异常对象
内置对象分类
作用域对象(四大作用域)
PageContext pageContext 当前页面
HttpServletRequest request 一次请求
HttpSession session 一次会话(多次请求)
ServletContext application 整个应用
共同特征:
四个作用域在一定程度上就是四个容器,都可以存储数据.就可以使用做个作用域进行数据的传递.
1.设置作用域中数据:
setAttribute(key, value)
2.从作用域中获取数据
getAttribute(key)
3.从作用域中删除数据
removeAttribute(key)
4.从作用域中获取所有数据对应的key值
getAttributeNames()
响应对象
HttpServletResponse response 响应对象
表示服务器与客户端会话时,做出响应的对象.
输出对象
out 向当前页面输出信息
当前类相关对象
ServletConfig config 配置对象 配置当前Servlet
java.lang.Object page 当前类对象 this
异常对象
Throwable exception 异常对象
当页面发生异常时,该对象由程序自动生成.
内部转发和重定向
内部转发:
request.getRequestDispatcher("转发的地址").forward(request,response);
重定向:
response.sendRedirect("重定向地址");
重定向和内部转发对比:
相同点:
重定向和内部转发都能实现当前浏览器窗口内容发生改变,都是页面跳转.
不同点:
1、内部转发只需要请求一次,服务器内部自己将请求信息和响应地址转交给下一个资源信息处理。而重定向,则是服务器告诉浏览器,重新请求新的资源地址.
2、内部转发URL地址不会发生改变,重定向由于是由浏览器重新发起的请求,URL地址会发生改变
3、由于内部转发,虽然页面发生改变,但是请求始终是一次,可以使用request作用域传输数据.但是重定向是多次请求,所以无法使用request作用域传递数据.
注意:
1.在使用request对象传递数据时,可以传递任意对象.而使用重定向传递数据时,只能在URL地址上进行拼接处理.即重定向传递数据只能当做字符串传递.本质上是告诉浏览器请求新的资源信息时,带的参数.
2.在实际的开发使用中,能使用重定向的尽量使用重定向.因为内部转发时,如果页面进行刷新,内部转时期间所有的相关业务会重新执行一遍,加大服务器压力,且容易引起业务异常.而重定向只是请求当前需要资源,刷新页面时,只会请求当前资源,相对而言压力较小.
JSP 指令
JSP 指令用来设置整个 JSP 页面相关的属性,如网页的编码方式和脚本语言。
指令可以有很多个属性,每个属性以键值对的形式存在,多个属性之间用空格隔开。
JSP 中的三种指令标签:
指令 | 描述 |
---|---|
<%@ page ... %> | 定义网页依赖属性,比如脚本语言、error 页面、缓存需求等等 |
<%@ include ... %> | 包含其他文件 |
<%@ taglib ... %> | 引入标签库的定义 |
注意:
include 指令: 引入其他文件, 引入时,被引入的文件会和当前文件一起编译.
JSP动作
JSP动作简介
与 JSP 指令元素不同的是,JSP 动作元素在请求处理阶段起作用。JSP 动作元素是用 XML 语法写成的。
利用 JSP 动作可以动态地插入文件、重用 JavaBean 组件、把用户重定向到其它的页面、为 Java 插件生成 HTML 代码。动作元素只有一种语法,如下:
<jsp:action_name attribute="value" />
动作元素基本上都是预定义的函数,JSP 规范定义了一系列的标准动作,它用 JSP 作为前缀,可用的标
准动作元素如下:
语法 | 描述 |
---|---|
jsp:include | 在页面被请求的时候引入一个文件。 |
jsp:useBean | 寻找或者实例化一个 JavaBean。 |
jsp:setProperty | 设置 JavaBean 的属性。 |
jsp:getProperty | 输出某个 JavaBean 的属性。 |
jsp:forward | 把请求转发到一个新的资源。 |
jsp:plugin | 根据浏览器类型为 Java 插件生成 OBJECT 或 EMBED 标记。 |
jsp:element | 定义动态 XML 元素 |
jsp:attribute | 设置动态定义的 XML 元素属性。 |
jsp:text | 在 JSP 页面和文档中使用写入文本的模板 |
注意:
jsp:include 引入指定文件.但是被引入的文件会和当前文件分别进行编译.
处理Form表单提交的数据
在tomcat 8之后,tomcat默认的编码格式设置为了UTF-8编码,这种编码只对get请求生效.此时使用get提交中文,不会出现乱码.若使用post提交,则会出现乱码.
注意:tomcat 8 以下,要进行编码配置:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
解决方案:
1.设置编码格式
2.对字符串进行转码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="formController.jsp" method="post">
<p>
普通文本框:<input type="text" name="userName" />
</p>
<p>
密码框:<input type="password" name="password" />
</p>
<p>
下拉框:
<select name="selectName">
<option value="值1">显示的文本1</option>
<option value="值2">显示的文本2</option>
<option value="值3">显示的文本3</option>
</select>
</p>
<p>
复选框:
<input type="checkbox" name="like" value="篮球">篮球
<input type="checkbox" name="like" value="足球">足球
<input type="checkbox" name="like" value="羽毛球">羽毛球
</p>
<p>
单选按钮:
<input type="radio" name="sex" value="男">男
<input type="radio" name="sex" value="女">女
<input type="radio" name="sex" value="不知道">不知道
</p>
<textarea rows="10" cols="10" name="textName"></textarea>
<input type="submit" value="提交"/>
</form>
</body>
</html>
<%@page import="java.util.Arrays"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 设置编码格式
// request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
// 先按照本身的编码格式进行转化为字节,按照新的编码格式进行编码
userName = new String(userName.getBytes("ISO-8859-1"),"UTF-8");
String password = request.getParameter("password");
String selectName = request.getParameter("selectName");
String like = request.getParameter("like");
// 根据名称 获取数组值
String[] likes = request.getParameterValues("like");
String sex = request.getParameter("sex");
String textName = request.getParameter("textName");
System.out.println("userName:"+userName);
System.out.println("password:"+password);
System.out.println("selectName:"+selectName);
System.out.println("likes:"+Arrays.toString(likes));
System.out.println("sex:"+sex);
System.out.println("textName:"+textName);
%>
EL表达式
JSP为了更好的获取作用域中的数据,提供了EL表达式的技术.可以写在JSP页面任何地方.注意,写在JS里面时,只能获取字符串.
这个EL表达式的这个技术,最核心的功能是获取作用域中的数据.语法:
${name值}
EL表达式,优先从: pageContext --> request ---> session --> application,如果以上作用域中,查找key对应的值,都找不到,则返回空字符串.
EL表达式获取JavaBean类型
语法:
${key.对象属性名}
示例:
<%@page import="com.sxt.bean.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
User user = new User(1,"韩梅梅");
request.setAttribute("userKey", user);
%>
${userKey.id}
${userKey.name}
</body>
</html>
注意:
1.el表达式,在获取对象的属性值是,调用的get方法,其本质与属性是没有关系的.而是调用get方法,将对象属性名首字母大写,与get字符串进行拼接,组成了get方法.调用该方法,获取值.只是,在开发中,每个属性其get和set方法,按照规则生成的.所以EL表达式,利用这个规则,获取属性值.
2.基于第一点,在实际开发中,可以对数据进行格式化.
package com.sxt.bean;
import java.text.SimpleDateFormat;
import java.util.Date;
public class User {
private Integer id;
private String name;
private Integer sex; // 1 男 2 女
private Date date;
public User() {}
public User(Integer id, String name, Integer sex) {
super();
this.id = id;
this.name = name;
this.sex = sex;
}
public Integer getId() {
System.out.println("我是ID属性的get方法");
return id+10;
}
public String getName() {
System.out.println("我是name属性的get方法");
return name;
}
public Integer getSex() {
return sex;
}
public String getSexFormat() {
if(sex != null) {
return sex == 1?"男":"女";
}
return "未知";
}
public void setSex(Integer sex) {
this.sex = sex;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDateFormate() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
return simpleDateFormat.format(date);
}
}
<%@page import="java.util.Date"%>
<%@page import="com.sxt.bean.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
User user = new User(1,"韩梅梅",2);
user.setDate(new Date());
request.setAttribute("userKey", user);
%>
${userKey.id}
${userKey.name}
${userKey.sex}
${userKey.sexFormat}
${userKey.date}
<!-- 调用get中的方法时把get去除后首字母小写进行调用 -->
${userKey.dateFormate}
</body>
</html>
EL表达式获取Map数据
语法:
${key.map中key}
示例:
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Date"%>
<%@page import="com.sxt.bean.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("key1", "value1");
map.put("key2", "value2");
Map<String,User> userMap = new HashMap<String,User>();
userMap.put("userKey",new User(1,"韩梅梅",2));
request.setAttribute("mapKey", map);
request.setAttribute("userMapKey", userMap);
//
Map<String,String> data = new HashMap<String,String>();
data.put("1","1的值");
request.setAttribute("data", data);
%>
${mapKey}<br>
${mapKey.key1}<br>
${mapKey.key2}<br>
<hr>
${userMapKey.userKey.id}
${userMapKey.userKey.name}
${userMapKey.userKey.sex}
${userMapKey.userKey.sexFormat}
<hr>
<!-- 不推荐这样使用 -->
${data['1']}
</body>
</html>
EL表达式获取List中的数据
语法:
${key[下标]}
示例:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Date"%>
<%@page import="com.sxt.bean.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
List<String> strs = new ArrayList<String>();
strs.add("韩梅梅");
strs.add("李磊");
strs.add("李华");
strs.add("Jim");
request.setAttribute("listKey", strs);
List<User> users = new ArrayList<User>();
users.add(new User(1,"韩梅梅",2));
users.add(new User(2,"李磊",1));
request.setAttribute("usersKey", users);
%>
${listKey}<br>
${listKey[0]}<br>
${listKey[1]}<br>
${listKey[2]}<br>
${listKey[3]}<br>
<hr>
${usersKey[0].name}<br>
${usersKey[1].name}<br>
</body>
</html>
EL表达式运算符
算术运算符
EL表达式支持数学运算符号
\+ \- \* \\
示例:
<h1>算术运算符</h1>
${1 + 2}<br>
${1 - 2}<br>
${1 * 2}<br>
${1 / 2}<br>
逻辑运算符
&& | and |
---|---|
|| | or |
! | not |
示例:
<h1>逻辑运算符</h1>
<!--
&& and
|| or
! not
-->
${true&&false}<br>
${true and false}<br>
${false || true}<br>
${false or true}<br>
${!false}<br>
${not false}<br>
比较运算符
> | gt |
---|---|
< | lt |
>= | ge |
<= | le |
== | eq |
!= | ne |
<h1>比较运算符</h1>
${1 > 2 } <br>
${1 gt 2 } <br>
${1 >= 1 } <br>
${1 ge 1 } <br>
${1 < 1 } <br>
${1 lt 1 } <br>
${1 <= 1 } <br>
${1 le 1 } <br>
${1 == 1 } <br>
${1 eq 1 } <br>
${1 != 1 } <br>
${1 ne 1} <br>
三元运算符
<h1>三元运算符</h1>
${1>2?'我是1':'我是2'}
empty运算符
判断字符串或者List是否是null或者空.若是null或者空则返回true,否则false
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL表达式运算符</title>
</head>
<body>
<%
String str = null;
String str1 = "";
String str2 = "我是字符串";
List<String> list1 = null;
List<String> list2 = new ArrayList<String>();
List<String> list3 = new ArrayList<String>();
list3.add("字符串");
request.setAttribute("str", str);
request.setAttribute("str1", str1);
request.setAttribute("str2", str2);
request.setAttribute("list1", list1);
request.setAttribute("list2", list2);
request.setAttribute("list3", list3);
%>
${empty str}<br>
${empty str1}<br>
${empty str2}<br>
${empty list1}<br>
${empty list2}<br>
${empty list3}<br>
</body>
</html>
EL表达式的不足
1、无法很好处理数数组结构的数据,例如:List
2、当作用域中的数据发生重叠覆盖时,默认是从最小作用域pageContext取值。
使用JSTL弥补EL表达式的不足
EL表达式从指定作用域取值
当4大作用域,属性发生重叠时,可以使用指定作用域关键字获取值
pageContext | pageScope |
---|---|
request | requestScope |
session | sessionScope |
application | applicationScope |
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EL从指定作用域取值</title>
</head>
<body>
<%
pageContext.setAttribute("name", "韩梅梅");
request.setAttribute("name", "李磊");
session.setAttribute("name", "Lucy");
application.setAttribute("name", "Lily");
/*
pageScope 表示 page作用域
requestScope 表示 request 作用域
sessionScope 表示session 作用域
applicationScope 表示application 作用域
*/
%>
${pageScope.name}<br>
${requestScope.name}<br>
${sessionScope.name}<br>
${applicationScope.name}<br>
</body>
</html>
JSTL
由于EL表达式存在一些不足,例如:
条件分支,循环分支等等.JSTL进行补充.在使用JSTL时,是第三方扩展包.首先要引入jstl相关jar包.JSTL是一套标签库.
由于JSTL标签库,一般约定使用字母c作为前缀,所以jstl标签也被称之为c标签
使用步骤
1、导入相关jar包
jstl-1.2.jar standard-1.1.2.jar
jstl-1.2.jar
standard-1.1.2.jar
2、引入jstl标签库
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
其核心功能:
条件分支
<c:if test="el表达式">
内容
</c:if>
语法解释:
当test中的表达式运算结果为true ,则执行被包裹的内容,否则不执行
示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--
c:if test="表达式"
内容
/c:if
-->
<%
request.setAttribute("v", 1);
%>
<c:if test="${v != 1}">
显示的内容
</c:if>
</body>
</html>
多条件分支
语法:
<c:choose>
<c:when></c:when>
<c:when></c:when>
<c:otherwise></c:otherwise>
</c:choose>
语法解释:
自上而下,满足when中的条件时,则执行相应的代码,且后面的不执行.若都不满足则执行otherwise
示例:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:choose>
<c:when test="${1!=1}">
我是第13行
</c:when>
<c:when test="${1!=1}">
我是第16行
</c:when>
<c:otherwise>
我是第19行
</c:otherwise>
</c:choose>
</body>
</html>
循环分支
语法:
<c:forEach> </c:forEach>
属性 | 解释 |
---|---|
item | 待循环的数据项 |
var | 具体待循环项的别名 |
step | 步长 每次循环自增值 默认1 |
begin | 开始循环下标 |
end | 结束循环下标 |
varStatus | 循环属性对象 |
index 索引下标 count 循环的次数 first 是否第一个 last 是否最后一个 |
示例:
<%@page import="java.util.ArrayList"%>
<%@page import="com.sxt.bean.User"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
List<User> users = new ArrayList<User>();
users.add(new User(1,"韩梅梅"));
users.add(new User(2,"李磊"));
users.add(new User(3,"Lily"));
users.add(new User(4,"Lucy"));
request.setAttribute("usersKey", users);
%>
<c:forEach items="${usersKey}" var="user" step="1" begin="0" end="1" varStatus="state">
${state.index} ${state.count} ${state.first} ${state.last} ${user.name}<br>
</c:forEach>
</body>
</html>
格式化
引入格式化标签库:
时间格式化:
<%@page import="java.util.Date"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.sxt.bean.User"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Date d = new Date();
request.setAttribute("d", d);
%>
<fmt:formatDate value="${d}" pattern="yyyy年MM月dd日 HH:mm:ss" var="time"/>
${time}<br>
${time}<br>
</body>
</html>