17.文件上传与下载
18.jsp 安全模式
19.EL 的基本语法
20.EL 隐含对象
21.相对路径与绝对路径
22.ajax 提交数据
23.JSTL 常用标签库
24.JSTL 扩展标签库
25.项目考核
17.文件上传与下载
JSP 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。
文件上传时 servlet 需要用注解 @MultipartConfig 修饰。同时前段表单需要指定 enctype="multipart/form-data"。
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
Part file = request.getPart("file");
if (file != null && file.getSize() != 0) {
String fileName = file.getSubmittedFileName();
System.out.println(fileName);
file.write("E:/ideaProject/jsp/web/aa.png");
response.getWriter().write("上传成功");
}
}
}
前端 jsp
<form action="upload" enctype="multipart/form-data" method="post">
选择文件<input type="file" name="file1"/>
<input type="submit" name="upload" value="上传"/>
</form>
关于文件上传的位置建议使用相对路径并将其挂载到 tomcat,否则上传文件无法预览。
文件下载
一般如果文件存放在 tomcat 中,则直接请求文件路径即可获取文件。所以本节文件是在 tomcat 之外,无法通过 tomcat 直接获取的。使用 Servlet 下载一般要指定响应的 ContentType,以及下载的文件名,代码如下:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
@WebServlet("/down")
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/x-msdownload");
//文件下载时必须设置响应头如上
String fileName = "中文.txt";
//文件下载时浏览器端的文件名
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
OutputStream outputStream = response.getOutputStream();
InputStream inputStream = new FileInputStream("C:\\ProgramData\\DisplaySessionContainer1.log");
byte[] bytes = new byte[1024];
int read;
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
inputStream.close();
}
}
18.jsp 安全模式
在实际开发中,jsp 一般不能直接访问,因为其页面未携带数据。一张空的 jsp 意义并不大。通常都是请求对应的 servlet 获取数据,转发到对应的 jsp。
就算页面不需要数据也可以通过 servlet 转发。这样做的好处还有一个好处是请求地址不再包含 .jsp 后缀。这对隐藏后台框架也是一种很好的保护。
通常将 jsp 放入 WEB-INF 目录下即可保护 jsp 页面。访问 jsp 必须经过 servlet 转发才能访问。这样就可以在 servlet 中校验权限等。
jsp 安全模式开发守则:
- 每个 jsp 对应一个 Servlet,如:index.jsp 对应 IndexServlet、login.jsp 对应 LoginServlet。
- 任何重定向操作都不能重定向 jsp 页面,而是重定向 Servlet,也不能随意用转发代替重定向。
- 编写系统的顺序为:jsp -> servlet ->filter,不能一开始就把 filter 写了拦截了所有请求导致页面或 Servlet 无法访问。
- 不能在 jsp 页面编写大量的 java 代码,jsp 从本质上理解为展示层面的组件。
案例:
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("aa","数据");
request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request,response);
}
}
欢迎页配置:web.xml 中默认欢迎页为 index.html 和 index.jsp ,如果需要配置为 Servlet 地址也可以使用如下方式。在项目启动后或打开项目的根路径自动调用该 Servlet。
<welcome-file-list>
<welcome-file>index</welcome-file>
</welcome-file-list>
19.EL 的基本语法
EL 表达式语法非常简单,它以“${"开头,以"}"结束,中间为合法的表达式,具体的语法格式如下:
${expression}
expression:用于指定要输出的内容,可以是字符串,也可以是由 EL 运算符组成的表达式。在 EL 表达式中要输出一个字符串,可以将此字符串放在一对单引号或双引号内。
注意:由于 EL 表达式的语法以"${"开头,所以如果在 JSP 网页中要显示"${" 字符串,必须 在前面加上\”符号,即"\${"来输出"${" 符号。
EL 的保留关键字
在为变量命名时,应该避免使用这些关键字,包括使用 EL输出已经保存在作用城范围内的变量,也不能使用关键字,如果已经定义了,那么需要修改为其他 的变量名。
gt eq or and div empty instanceof false ge le It not
通过 EL 访问对象内数据
通过 EL 提供的“[]”和“.”运算符可以访问数据。通常情况下,“[]“和“.”运算符是等价的,可以相互代替。
${user.id}<br/>${user['.name']}
但是也不是所有情况下都可以相互替代,例如,当对象的属性名中包括一些特殊的符号(-或.)时,就只能使用“[”运算符来访问对象的属性。例如,${userInfo['user-id']} 是正确的,而 ${userIfo.user-name} 则是错误的。另外,EL 的“[”运算符还有一个用途,就是用来获取数组或者 List 集合中的数据,下面进行详细介绍。
数组元素的获取
应用“[”运算符可以获取数组的指定元素,但是“.”运算符则不能。
${arrBook[0]}
案例:
在 request 域中存入四本书,使用循环将编号和书名输出到页面上。
<%
String[] arr = {"java", "ui", "大数据", "新媒体"};
%>
<%
for (String s : arr) {
request.setAttribute("b", s);
%>
<p>${b}</p>
<%
}
%>
在 EL 中,也可以进行算术运算,同 Java 语言一样,EL 提供了加、减、乘、除和求余 5 种算术运 算符。
+ - * /(div) %(mod)
5.EL 判断非空
在 EL 中,判断对象是否为空,可以通过 empty 运算符实现,该运算符是一个前缀(prefix) 运算符,即 empty 运算符位于操作数前方,用来确定一个对象或变量是否为 null 或空。另外,empty 运算符也可以与 not 运算符结合使用,用于判断一个对象或变量是否为非空。
${empty expression}
${not empty expression}
6.EL 运算符
在 EL 中,提供了 6 种关系运算符。这6种关系运算符不仅可以用来比较整数和浮点数,还可以用来比较字符串。关系运算符的使用格式如下:
==或eq 等于
!=或ne 不等于
<或lt 小于
>或gt 大于
<=或le 小于等于
>=或ge 大于等于
在进行比较运算时,如果涉及两个或两个以上的判断条件时,就需要应用逻辑运算符。逻辑运算符的条件表达式的值必须是 Boolean 型或是可以转换为Boolean 型的字符串,并且返回的结果也是 Boolean 型。
&&或and 与
||或or 或
!或not 非
7.EL 字符串类型的变量拼接时,不能使用 +,需要使用 concat() 方法。
${"2"+"1"} 得到结果为3
${"hello"+" world!"} 报错 java.lang.NumberFormatException: For input string: "hello"
${"hello".concat(" world")} 得到结果为hello world
20.EL 隐含对象
在 EL 中提供了 4 个用于访问作用域范围的隐含对象,即 pageScope、requestScope、sessionScope 和 applicationScope。运用这 4 个隐含对象指定所要查找的标识符的作用域后,系统将不再按照默认的顺序 page、request、session 及 application 来查找相应的标识符。它们与 JSP 中的 page、request、session 及 application 内置对象类似。只不过这 4 个隐含对象只能用来取得 setAttribute 范围内的属性值,而不能取得其他相关信息。
<%
pageContext.setAttribute("id", 8);
session.setAttribute("id", 2);
request.setAttribute("id", 1);
application.setAttribute("id", 3);
%>
${sessionScope.id}
为了能够获得 Web 应用程序中的相关数据,EL 提供了多个隐含对象,这些对象类似于 JSP 的内置对象,也是直接通过对象名进行操作。在 EL 的隐含对象中,除 pageContext 是 JavaBean 对象,其他的隐含对象都对应于 java.util.Map 类型。
pageContext 可以访问 JSP 内置对象(如 request、response、out、session、exception 和 page 等。在获取到这些内置对象后,就可以获取其属性值。这些属性与对象的 getXXX() 方法相对应,在使用时,去掉方法名中的 get,并将首字母改为小写即可。
1.访问 request 对象
通过pageContext获取JSP内置对象中的request对象,可以使用下面的语句:
${pageContext.request}
获取到 request 对象后,就可以通过该对象获取与客户端相关的信息。例如,HTTP 报头信息、客户信息提交方式、客户端主机 IP 地址和端口号等。
${pageContext.request.severPort}
2.访问 response 对象
通过 pageContext 获取JSP内置对象中的 response 对象,可以使用下面的语句:
${pageContext.response}
获取到 response 对象后,就可以通过该对象获取与响应相关的信息。 ${pageContext.response.contentType}这句代码将返回响应的内容类型。
3.访问 out 对象
通过 pageContext 获取 JSP 内置对象中的 out 对象,可以使用下面的语句:
${pageContext.out}
获取到 out 对象后,就可以通过该对象获取与输出相关的信息。${pageContext.out.bufferSize } 这句代码将返回输出缓冲区的大小。
4.访问 session 对象
通过 pageContext 获取JSP内置对象中的 session 对象,可以使用下面的语句:
${pageContext.session}
获取到 session 对象后,就可以通过该对象获取与session相关的信息。 ${pageContext.session.maxlnactiveInterval} 这句代码将返回 session 的有效时间。
5.访问 exception 对象
通过 pageContext 获取JSP内置对象中的 exception 对象,可以使用下面的语句:
$(pageContext.exception}
获取到 exception 对象后,就可以通过该对象获取 JSP 页面的异常信息。 ${pageContext.excepion.message}
6.访问 page 对象
通过 pageContext 获取 JSP 内置对象中的 page 对象,可以使用下面的语句:
${pageContext.page}
获取到 page 对象后,就可以通过该对象获取当前页面的类文件。${pageContext.page.class} 这句代码将返回当前页面的类文件。
7.访问 servletContext 对象
通过 pageContext 获取 JSP 内置对象中的 servletContext 对象,可以使用下面的语句: ${pageContext.servletContext}
获取到 servletContext 对象后,就可以通过该对象获取 servlet 上下文信息。 ${pageContex.request.contextPath} 这句代码将返回当前页面的上下文路径。
8.param 可以获取请求里面的参数。如:${param.id} 可以获取请求 XXX?id=12 的这种参数。
21.相对路径与绝对路径
绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)
例如: C://xyz/test.txt 代表了 test.txt 文件的绝对路径。Hardware | Oracle 也代表了一个 URL 的绝对路径。
相对路径:相对与某个基准目录的路径。包含 Web 的相对路径(HTML 中的相对目录),例如:在 Servlet 中,"/"代表 Web 应用的跟目录。和物理路径的相对表示。
例如:"./" 代表当前目录,"../"代表上级目录。这种类似的表示,也是属于相对路径。
注意 JSP/Servlet 中的相对路径分为服务端和客户端路径。
1.服务器端的地址
服务器端的相对地址指的是相对于 web 应用的地址,这个地址是在服务器端解析的(不同于 html 和 javascript 中的相对地址,他们是由客户端浏览器解析的)也就是说这时候在 jsp 和 servlet 中的相对地址应该是相对于 web 应用,即相对于 http: //192.168.0.1/webapp/ 的。
其用到的地方有:
转发:servlet 中的 request.getRequestDispatcher(address);这个 address 是在服务器端解析的,所以,要转发到 jsp/a.jsp 应该这么写:request.getRequestDispatcher(“/jsp/a.jsp”) 前面 / 相对于当前的 web 应用 webapp,其绝对地址就是:http://192.168.0.1/webapp/jsp/a.jsp。
重定向:在 jsp 或 Servlet 中 response.sendRedirect("/上下文路径/jsp/a.jsp");
2.客户端的地址
所有的 html 页面中的相对地址都是相对于服务器根目录(http://192.168.0.1/)的,而不是(跟目录下的该 Web 应用的目录)http://192.168.0.1/webapp/ 的。 Html 中的 form 表单的 action 属性的地址应该是相对于服务器根目录(http://192.168.0.1/)的,所以,如果提交到 a.jsp 为:action="/webapp/user/a.jsp"或 action="上下文路径/user/a.jsp; 提交到 servlet 为 actiom="/webapp/handleservlet" Javascript 也是在客户端解析的,所以其相对路径和 form 表单一样。 因此,一般情况下,在 JSP/HTML 页面等引用的 CSS,Javascript 等属性前面最好都加上上下文路径,以确保所引用的文件都属于 Web 应用中的目录。另外,应该尽量避免使用类似"."、"./"、"../../" 等类似的相对该文件位置的相对路径,这样当文件移动时,很容易出问题。
<img src="${pageContext.request.contextPath}/img/1.jpg"/>
<form action="${pageContext.request.contextPath}/login">
<input type="submit" value="提交"/>
</form>
(学习QQ群:330737900) 练习: 内容修改(无内容)
(学习QQ群:330737900) 答案: 内容修改(无内容)
22.ajax 提交数据
ajax 提交数据一般需要 jquery,而且页面不再使用 submit 类型的按钮,数据在点击按钮时便会使用 jquery 发送请求。发送的数据会找到对应的 Servlet 获得后台返回的数据,并且调用回调方法将数据放在 response 变量中。
<form>
<input name="name" id="name"/>
<input name="password" id="password"/>
<p id="msg"></p>
<input type="button" value="提交" onclick="sub()"/>
</form>
<script>
function sub(){
let name = $("#name").val();
let password = $("#password").val();
//回调
$.post("login", {name, password}, function (response) {
$("#msg").html(response)
})
}
</script>
LoginServlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String password = req.getParameter("password");
System.out.println(name);
System.out.println(password);
resp.getWriter().write("登录成功");
}
}
案例:全 HTML 的登录退出系统 index.html,login.html,loginServlet,LogoutServlet,UserInfoServlet,LoginFilter
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<h1>欢迎<span id="user"></span>登录!</h1>
<a href="logout">退出登录</a>
<script>
$.post("userInfo", {}, function (response) {
$("#user").html(response)
})
</script>
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
<form>
<input name="name" id="name"/>
<input name="password" id="password"/>
<p id="msg"></p>
<input type="button" value="提交" onclick="sub()"/>
</form>
<script>
function sub() {
let name = $("#name").val();
let password = $("#password").val();
//回调
$.post("login", {name, password}, function (response) {
if (response.trim() == '登录成功') {
location.href = "index.html";
} else {
$("#msg").html(response)
}
})
}
</script>
</body>
</html>
loginServlet
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String password = req.getParameter("password");
if ("123".equals(password)) {
req.getSession().setAttribute("userInfo", name);
resp.getWriter().println("登录成功");
} else {
resp.getWriter().println("账号或密码错误");
}
}
}
LogoutServlet
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().invalidate();
resp.sendRedirect("login.html");
}
}
UserInfoServlet
@WebServlet("/userInfo")
public class UserInfoServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.getWriter().println(req.getSession().getAttribute("userInfo"));
}
}
LoginFilter
@WebFilter("/*")
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getRequestURI().contains("login")) {
filterChain.doFilter(request, response);
return;
}
if (request.getSession().getAttribute("userInfo") != null) {
filterChain.doFilter(request, response);
return;
}
response.sendRedirect("login.html");
}
@Override
public void destroy() {
}
}
23.JSTL 常用标签库
JSTL 全称为 JSP Standard [ˈstændəd] Tag Library [ˈlaɪbrəri]即 JSP 标准标签库。JSTL 作为最基本的标签库,提供了一系列的 JSP 标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等等。使用 JSTL 标签库步骤如下:
1.导入 jstl-1.2.jar 开发包。
2.在 JSP 页面中用 tablib 指令引入需要用到的 JSTL 标签。
core 标签库
core 标签库是 JSTL 的核心标签库,实现了最基本的功能:流程控制、迭代输出等操作。core 标签库的前缀一般是 c
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
`c:out`
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
value | true | object | 指定要输出的内容 |
escapeXml | true | boolean | 指定是否将>、<、 &、'、” 等特殊字符进行 HTML 编码转换后再进行输出。默认值为 true |
default | true | object | 指定如果 value 属性的值为 null 时所输出的默认值 |
案例:
<%
request.setAttribute("name", "zhongfucheng");
%>
//<c:out/>标签支持标签体,default属性上的数据可以写在标签体中
//<c:out value="${name}" escapeXml="true">您要的数据找不着</c:out>
<c:out value="${name}" default="您要的数据找不着" escapeXml="true"/>
我们发现上面的代码实现的效果和 EL 表达式是一样的,它出色的地方就多了两个属性 default 和 escapeXml [ɪˈskeɪp]属性。如果我们用到这两个属性,我们就使用该标签,如果没有用到这两个属性就用 EL 表达式就可以了。
`c:if`
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
test | true | boolean | 决定是否处理标签体中的内容的条件表达式 |
var | false | string | 用于指定将 test 属性的执行结果保存到某个 Web 域中的某个属性的名称 |
scope | false | string | 指定将 test 属性的执行结果保存到哪 个 Web 域中 |
JSTL 提供了 if 标签完成分支语句的实现,test 属性是不可或缺的。 var 和 scope 属性我看来好像没什么用的(保存执行结果有什么用?)
案例:
<%--如果带过来的名字是zhangsan,那么可以登陆--%>
<c:if test="${param.name=='zhangsan'}">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登陆"/>
</c:if><br/>
`c:choose`
if 标签没有 else 的功能,如果需要类似于 java 中的 if else 流程就需要使用 choose 标签。 choose 标签需要联合 when 和 otherwise 标签一起使用!
案例:
<c:choose>
<c:when test="${param.name=='张三'}">
你好啊,张三
</c:when>
<c:when test="${param.name=='李四'}">
你是李四吗?
</c:when>
<c:otherwise>
你是谁啊?别随便过来!
</c:otherwise>
</c:choose>
`c:forEach`
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
var | false | string | 用于指定将 test 属性的执行结果保存 到 page 域中的属性的名称 |
items | true | 任何类型 | 将要迭代的集合对象 |
begin | true | int | 如果指定items属性,就从集合中的第begin个元素开始进行迭代,begin的索引值从0开始编号;如果没有指定items属性,就从begin指定的值开始迭代,直到end值时结束迭代 |
end | true | int | 参考 begin 描述 |
step | true | int | 指定迭代的步长 |
varStatus | false | 当前被遍历对象的信息被记录在varStatus里 |
forEach 为循环标签,相当于 Java 中的 while 和 for
案例:
<%
List list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王二");
request.setAttribute("list", list);
%>
<c:forEach var="list" items="${list}" >
${list}<br/>
</c:forEach>
遍历Map对象有稍微地不一样,我们来看一下,var 属性保存的不是每个迭代的对象,而是 Map.Entry。
<%
Map map = new HashMap();
map.put("1", "张三");
map.put("2", "李四");
map.put("3", "王二");
request.setAttribute("map",map);
%>
<c:forEach var="me" items="${map}" >
${me.key} ${me.value}<br/>
</c:forEach>
begin 默认从 0 开始、end 默认为集合的最后一个元素、step 默认为 1
案例:
<c:forEach var="i" begin="1" end="10" step="1">
<c:out value="${i}" /><br/>
</c:forEach>
varStatus 代表着当前对象被迭代的信息,它有以下的属性。
- index【返回当前是第几个对象,从0开始计数】
- count【已经遍历多少个对象了,从1开始计数】
- first【是否是第一个】
- last【是否是最后一个】
- current【当前被迭代的对象】
- begin【开始的位置】
- end【最后的位置】
- step【步长】
案例:
<c:forEach var="list" items="${list}" varStatus="varStatus" >
${list}您的下标是:${varStatus.index}<br/>
</c:forEach>
24.JSTL 扩展标签库 (自学)
`c:forTokens`
该标签类似于 String 类的 split() 和 for 循环的一种集合 它与 forEach 标签非常相似,都有 begin、end、step、items、var、varStatus 属性,不同的是forTokens 标签的 items 属性里面是字符串,这个字符串会被 delims 属性的内容分割成多个字符串!
案例:
<c:forTokens items="张三,李四,王二,麻子" var="name" delims="," >
${name}
</c:forTokens>
`c:set`
属性名 | 是否支持EL | 属性类型 | 属性描述 |
---|---|---|---|
value | true | object | 指定要输出的内容 |
var | false | string | 用于指定要设置的Web域属性的名称 |
scope | false | string | 用于指定属性所在的Web域 |
target | true | object | 用于指定要设置属性的对象,这个对象必须 是 JavaBean 对象或 java. util. Map 对象 |
property | true | string | 用于指定当前要为对象设置的属性名称 |
该标签有5个属性,用起来有稍微有些复杂了!现在要记住的就是:var属性操作的是Integer、Double、Float、String等类型的数据,target属性操作的是JavaBean或Map对象的数据,scope代表的是Web域,value是值,property是对象的属性!
使用 var 属性
既然var属性只能操作Integer、Double、String等类型,那么存在var属性就一定没有property属性(property代表的是对象的成员属性,Integer、String这些类型哪来的成员变量呀)
下面的案例是这样的:创建了一个name的变量,设置的值为zhongfucheng,范围是page
<c:set var="name" value="fucheng" scope="page"/>
${name}
当然了,set标签也支持标签体,value的值可以写在标签体里边
<c:set var="name" scope="page">
zhongfucheng
</c:set>
使用 var 属性和 scope 属性实现计数器
<%--由于下面变量需要做加法运算,所以要定义出来,不然服务器是不知道我的变量是Integer类型的--%>
<%
Integer sessionCount = 0;
Integer applicationCount = 0;
%>
<c:set var="sessionCount" value="${sessionCount+1}" scope="session"/>
<c:set var="applicationCount" value="${applicationCount+1}" scope="application"/>
使用 target 属性与之配对的是 property 属性,target 属性只能操作 JavaBean 或 Map 对象,property 就是对应的成员变量或 key 了。。
既然 target 属性操作的是 JavaBean或Map对象,那么一定是通过EL表达式来获取到对象了。taget属性如果获取不到数据会抛出异常!使用target属性就一定没有scope属性(scope属性代表的是保存范围,target的值都是获取来的,难道你还能改变人家的范围?)
<%--创建出JavaBean对象,设置为session范围的属性--%>
<jsp:useBean id="person" scope="session"/>
<%--获取到person对象,设置age属性的值为32--%>
<c:set target="${person}" property="age" value="32"/>
${person.age}
`c:remove`
remove标签就相当简单了,只有 var 和 scope 属性,代表的是删除域范围的属性
案例:
<%--创建出JavaBean对象,设置为session范围的属性--%>
<jsp:useBean id="person" scope="session"/>
<%--获取到person对象,设置age属性的值为32--%>
<c:set target="${person}" property="age" value="32"/>
${person.age}
<br/>
<%--删除session属性--%>
<c:remove var="person" scope="session"></c:remove>
${person.age==null?"存在session的person对象被删除了!":"我还在呢!"}
`c:catch`
该标签主要用来处理程序中产生的异常。 catch标签也十分简单,只有一个var属性,var属性封装了异常的信息!
<%--创建出JavaBean对象,设置为session范围的属性--%>
<jsp:useBean id="person" scope="session"/>
<c:catch var="message">
<%--target属性只能是EL表达式,现在我是字符串,获取不到对象,肯定会抛出异常的!--%>
<c:set target="person" property="age" value="32"/>
</c:catch>
${message}
fmt 标签
jsp 页面需引入 fmt 标签:
<taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt">
使用如下代码将字符串型日期转换为日期型 。
<fmt:parseDate value="${personMaster.masterDate}" pattern="yyyy-MM-dd" var="masterDate"/>
使用如下代码对日期进行格式化。
<fmt:formatDate value="${masterDate}" pattern="yyyy-MM-dd" timeZone="GMT+08:00"/>
fn 标签
jsp 页面需引入 fn 标签:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
使用如下代码将字符串按照逗号切割成数组并遍历 。
<c:set value="${ fn:split('a,b,c,d,', ',') }" var="arr"/>
<c:forEach items="${arr}" var="s">
<p>${s}</p>
</c:forEach>
25.项目考核
旅游景区管理系统 travel-system,知识汇聚系统 knowledge-system,博客系统 blog-system、新闻系统 news-system、项目展示系统 project-display-system、内容管理系统 content-management-system、 。
1.挑选适当的前端页面模板,页面至少包含如下前后台需求,并将其汉化。根据模板设计数据库表(数据库设计文档,在设计时一般增加创建时间、最后修改时间、最后修改人编号、上下线、排序数字等)
2.使用面向对象开发思想完成项目开发,并使用如下的包结构 servlet(控制层),service(服务层),dao(数据库访问层),entity(模型),filter(过滤器层),util(工具类层)
3.挑选合适的后台管理页面模板,对所有的数据表进行增删改查,路径统一放在 /WEB-INF/jsp/admin/ 目录下,所有后台 Servlet 也加上父路径,如:/admin/index。
4.做好相应的权限控制,保证后台管理页面在未登录的情况下不能访问。
前台需求:
1.展示博客列表
2.展示博客详情
3.记录博客评论,注册,登录情况下可以评论
4.留言联系
管理需求:
1.系统大数据统计(博客总数量、上线数量、浏览量 top3、注册人数统计)
2.用户管理(删除,重置密码,锁定和启用)
3.博客管理(增加、删除、修改、上下线,评论管理)
4.留言管理(查看)
最后提交文件:
1.原项目模板
2.数据库设计文档(参考文档)
3.源代码和数据库脚本
4.可运行的项目及脚本
5.专业视频(介绍项目使用,从启动脚本开始演示)
6.专业 ppt