jsp servlet基础

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 安全模式开发守则:

  1. 每个 jsp 对应一个 Servlet,如:index.jsp 对应 IndexServlet、login.jsp 对应 LoginServlet。
  2. 任何重定向操作都不能重定向 jsp 页面,而是重定向 Servlet,也不能随意用转发代替重定向。
  3. 编写系统的顺序为:jsp -> servlet ->filter,不能一开始就把 filter 写了拦截了所有请求导致页面或 Servlet 无法访问。
  4. 不能在 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 代表着当前对象被迭代的信息,它有以下的属性。 

  1.  index【返回当前是第几个对象,从0开始计数】 
  2.  count【已经遍历多少个对象了,从1开始计数】 
  3.  first【是否是第一个】 
  4.  last【是否是最后一个】 
  5.  current【当前被迭代的对象】 
  6.  begin【开始的位置】 
  7.  end【最后的位置】 
  8.  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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值