Java Web简单学习路线相关案例

本文详细介绍了Java Web的学习路径,涵盖了JSP元素、JSP隐含对象、JDBC数据库访问、状态管理(Cookie、Session、Application)、数据源与JavaBean、分页技术、文件上传下载、Servlet基础、JSTL与EL以及AJAX基础。通过实例演示和课后作业,帮助读者深入理解每个概念和技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSP元素

一、JSP执行过程

Web容器处理JSP请求有三个阶段:转译(translate)——>编译(compile)——>解释(interpret)

客户端发出请求
Web容器将JSP转译成Servlet源代码
Web容器将产生的源代码进行编译
Web容器加载编译后的代码并执行
把执行结果响应至客户端

第一次请求之后,Web容器可以重用已经编译好的字节码文件。

注意:如果对JSP文件进行了修改,Web容器会重新对JSP文件进行翻译和编译。

二、JSP元素

创建Web项目JSPElementsDemo:
在这里插入图片描述
在web目录创建demo01.html页面:
在这里插入图片描述
在web目录里创建demo02.jsp页面:
在这里插入图片描述
demo02.jsp页面代码:

<%-- 页面指令 --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 标签库指令 --%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<html>
<head>
    <title>demo02</title>
</head>
<body>
    <%-- 包含指令 --%>
    <%@include file="demo01.html"%>

    <%-- 脚本元素 --%>
    <%
        String msg1 = "Welcome to JSP World!";
    %>

    <%-- 表达式元素 --%>
    <h3><%= msg1 %></h3>

    <%-- 采用标签库和表达式语言(EL:Expression Language)--%>
    <c:set var="msg2" value="Welcome to JSTL World!" scope="page"/>
    <h3><c:out value="${msg2}" /></h3>

    <c:set var="age" value="16" />
    <c:if test="${age >= 18}">
        <h3>欢迎访问本网站~</h3>
    </c:if>
    <c:if test="${age < 18}">
        <h3>本网站不欢迎你~</h3>
    </c:if>

    <c:choose>
        <c:when test="${age >= 18}">
            <h3>欢迎访问本网站~</h3>
        </c:when>
        <c:otherwise>
            <h3>本网站不欢迎你~</h3>
        </c:otherwise>
    </c:choose>

    <%-- 计算1+2+3+...+100的值 --%>
    <%-- (1)脚本方法 --%>
    <%
        int num=0;
        for(int i=1;i<=100;i++){
            num+=i;
        }
    %>
    <h3><%= num %></h3>
    <%-- (2)标签方法 --%>
    <c:set var="sum" value="0" />
    <c:forEach var="i" begin="1" end="100">
        <c:set var="sum" value="${sum + i}" />
    </c:forEach>
    <h3>1+2+3...+100=${sum}</h3>
    <h3>1+2+3...+100=<c:out value="${sum}" /> </h3>
</body>
</html>

启动服务器访问http://localhost:8080/JSPElementsDemo/demo02.jsp:
在这里插入图片描述
包含动作元素jsp:include演示:
在这里插入图片描述
在这里插入图片描述
启动服务器,访问http://localhost:8080/JSPElementsDemo/demo03.jsp:
在这里插入图片描述
转发动作元素jsp:forward演示:
在这里插入图片描述
在这里插入图片描述
在src里创建net.hw.bean包,在里面创建User实体类:
在这里插入图片描述
User实体代码:

package net.xsp.bean;

/**
 * 功能:用户实体类
 * 日期:2019年9月12日
 */
public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

在这里插入图片描述
任务:不用useBean动作元素,用脚本元素与表达式元素来完成上述任务。

<%@ page import="net.xsp.bean.User" %>
<%--
  Created by IntelliJ IDEA.
  User: Stranger
  Date: 2019/9/12
  Time: 10:19
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>demo07</title>
</head>
<body>
    <%-- 创建用户实体对象 --%>
    <jsp:useBean id="user" class="net.xsp.bean.User" scope="page"/>

    <%-- 设置实体属性 --%>
    <jsp:setProperty name="user" property="id" value="1"/>
    <jsp:setProperty name="user" property="username" value="xsping"/>
    <jsp:setProperty name="user" property="password" value="123456"/>

    <%-- 获取实体属性值 --%>
    <h3>id: <jsp:getProperty name="user" property="id"/></h3>
    <h3>username: <jsp:getProperty name="user" property="username"/></h3>
    <h3>passord: <jsp:getProperty name="user" property="password"/></h3>

    <%-- 输出用户实体对象 --%>
    <h3><%= user %></h3>

    <%-- java脚本形式 --%>
    <%
        User u = new User();
        u.setId(2);
        u.setUsername("root");
        u.setPassword("654321");
    %>
    <h3>id: <%= u.getId() %></h3>
    <h3>username: <%= u.getUsername() %></h3>
    <h3>password: <%= u.getPassword() %></h3>
</body>
</html>

在这里插入图片描述
课后作业:编写JSP页面,计算2000~2019年期间有几个闰年。使用表达式输出结果。
在这里插入图片描述
在这里插入图片描述

JPS隐含对象

一、什么是JSP隐含对象

JSP隐含对象是 Web 容器创建的一组对象
JSP隐含对象的名称是JSP 的保留字
JSP隐含对象是可以直接在JSP页面使用的对象,无需使用“new”获取实例

二、JSP隐含对象

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、request对象

在这里插入图片描述
1.在web目录里创建用户注册页面register.jsp
在这里插入图片描述

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册</title>
    <script type="text/javascript" src="js/check.js"></script>
</head>
<body>
    <h3 style="text-align: center">用户注册</h3>
    <form action="do_register.jsp" method="post">
        <table border="1" cellpadding="10px" style="margin: 0px auto">
            <tr>
                <td align="center">用户名</td>
                <td><input type="text" id="username" name="username" size="35"></td> <!--设置表单元素的id属性是为了页面JavaScript代码能访问该元素,设置表单元素的name属性是为了表单的处理页面能够通过request.getParameter()方法获取到表单元素的值。-->
            </tr>
            <tr>
                <td align="center">密&nbsp;&nbsp;码</td>
                <td><input type="password" id="password" name="password" size="35"></td>
            </tr>
            <tr>
                <td align="center">你从哪里知道本网站</td>
                <td>
                    <input type="checkbox" name="channel" value="报刊">报刊
                    <input type="checkbox" name="channel" value="网络">网络
                    <input type="checkbox" name="channel" value="朋友推荐">朋友推荐
                    <input type="checkbox" name="channel" value="电视">电视
                </td>
            </tr>
            <tr align="center">
                <td colspan="2">
                    <input type="submit" value="提交" onclick="return checkForm();"> <!-- 为真继续执行下去,为假则不能通过此处验证 -->
                    <input type="reset" value="重置">
                </td>
            </tr>
        </table>
    </form>
    <!--
    <script type="text/javascript">
        function checkForm() {
            // 获取用户名与密码元素
            var txtUsername = document.getElementById("username");
            var txtPassword = document.getElementById("password");
            // 获取用户名与密码数据
            var username = txtUsername.value;
            var password = txtPassword.value;
            // 用户名非空校验
            if (username == "") {
                alert("注意:用户名不能为空!");
                txtUsername.focus(); //获取焦点,使焦点指向username
                return false; // 返回false使它不能通过
            }
            // 密码非空校验
            if (password == "") {
                alert("注意:密码不能为空!");
                txtPassword.focus();
                return false;
            }
            return true;
        }
    </script>
    -->
</body>
</html>

2.在web目录里创建处理注册页面do_register.jsp
在这里插入图片描述

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示注册信息</title>
</head>
<body>
    <%
        // 设置请求对象字符编码格式
        request.setCharacterEncoding("utf-8");
        // 读取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 读取渠道复选框的值
        String[] channels = request.getParameterValues("channel");
        StringBuffer buffer  = new StringBuffer();
        if (channels != null) {
            for (String channel: channels) {
                buffer.append(channel + " ");
            }
        }
    %>
    <h3>用户注册信息</h3>
    用户名: <%= username %><br/>
    密&nbsp;码: <%= password %><br/>
    渠&nbsp;道: <%= buffer.toString() %>
</body>
</html>

课堂练习:给用户注册页面添加表单校验,要求用户名与密码非空。
在这里插入图片描述
在这里插入图片描述
其实,我们可以将表单校验脚本提取出来创建一个js文件,然后导入页面来使用。
在这里插入图片描述
删除register.jsp页面里的脚本元素
在这里插入图片描述
导入check.js脚本
在这里插入图片描述
课后作业:注册页面信息的获取。给出了register.jsp,要求编写do_register.jsp,获取注册信息并显示。
在这里插入图片描述

四、response对象

在这里插入图片描述
1.在web目录里创建登录页面login.jsp
在这里插入图片描述
2.在web目录里创建登录处理页面do_login.jsp
在这里插入图片描述
3.在web目录里创建登录成功页面success.jsp
在这里插入图片描述
4.在web目录里创建登录失败页面failure.jsp
在这里插入图片描述

五、out对象

在这里插入图片描述
在这里插入图片描述

六、session 对象

long getCreationTime():取得session产生的时间,单位是毫秒
String getId():取得session 的ID
long getLastAccessedTime():取得用户最后通过这个session送出请求的时间
long getMaxInactiveInterval():取得最大session不活动的时间,若超过这时间,session 将会失效
void invalidate():取消session 对象,并将对象存放的内容完全抛弃
boolean isNew():判断session 是否为"新"的
void setMaxInactiveInterval(int interval):设定最大session不活动的时间,若超过这时间,session 将会失效
void setAttribute():设置session对象的属性
void getAtrribute():获取session对象的属性

案例演示:页面跳转传递会话属性数据
在这里插入图片描述
在这里插入图片描述

利用JDBC访问数据库

一、JDBC相关知识

在这里插入图片描述
在这里插入图片描述

二、创建数据库与表

在这里插入图片描述

三、实例演示——用户登录

创建Web项目LoginDemo01
在这里插入图片描述
User

package net.xsp.bean;

/**
 * 功能:用户实体类
 * 作者:
 * 日期:2019年10月10日
 */
public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

UserDao

package net.xsp.dao;

import net.xsp.bean.User;

/**
 * 功能:用户数据访问接口
 * 作者:
 * 日期:2019年10月10日
 */
public interface UserDao {
    /**
     * 登录方法
     *
     * @param username
     * @param password
     * @return true - 登录成功;false - 登录失败
     */
    boolean login(String username, String password);

    /**
     * 插入方法
     *
     * @param user
     * @return 插入记录数
     */
    int insert(User user);
}

UserDaoImpl

package net.xsp.dao.impl;

import net.xsp.bean.User;
import net.xsp.dao.UserDao;
import net.xsp.dbutil.ConnectionManager;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 功能:用户数据访问接口实现类
 * 作者:
 * 日期:2019年10月10日
 */
public class UserDaoImpl implements UserDao {
    /**
     * 登录方法
     *
     * @param username
     * @param password
     * @return true - 登录成功;false - 登录失败
     */
    @Override
    public boolean login(String username, String password) {
        // 声明标志变量
        boolean flag = false;
        // 声明数据库连接
        Connection conn = null;

        try {
            // 获取数据库连接
            conn = ConnectionManager.getConnection();
            // 定义SQL字符串
            String strSQL = "select * from t_user where username = ? and password = ?";
            // 创建预备语句对象
            PreparedStatement pstmt = conn.prepareStatement(strSQL);
            // 设置占位符的值
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            // 执行SQL查询,返回结果集
            ResultSet rs = pstmt.executeQuery();
            // 判断结果集里是否有记录
            if (rs.next()) {
                flag = true;
            } else {
                flag = false;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            ConnectionManager.closeConn(conn);
        }

        // 返回标志变量
        return flag;
    }

    /**
     * 插入方法
     *
     * @param user
     * @return 插入记录数
     */
    @Override
    public int insert(User user) {
        // 声明插入记录数变量
        int count = 0;
        // 声明数据库连接
        Connection conn = null;

        try {
            // 获取数据库连接
            conn = ConnectionManager.getConnection();
            // 定义SQL字符串
            String strSQL = "insert into t_user (username, password) values (?, ?)";
            // 创建预备语句对象
            PreparedStatement pstmt = conn.prepareStatement(strSQL);
            // 设置占位符的值
            pstmt.setString(1, user.getPassword());
            pstmt.setString(2, user.getPassword());
            // 执行SQL更新,返回更新记录数
            count = pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            ConnectionManager.closeConn(conn);
        }

        // 返回插入记录数
        return count;
    }
}

ConnectionManager

package net.xsp.dbutil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * 功能:数据库链接管理类
 * 作者:
 * 日期:2019年10月10日
 */
public class ConnectionManager {
    // 定义连接数据库的参数值
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/xspdb";
    private static final String USER = "root";
    private static final String PASSWORD = "1";

    /**
     * 私有化构造方法,拒绝实例化
     */
    private ConnectionManager() {
    }

    /**
     * 获取数据库连接静态方法
     *
     * @return 数据库连接
     */
    public static Connection getConnection() {
        // 声明数据库连接
        Connection conn = null;

        try {
            // 安装数据库驱动程序
            Class.forName(DRIVER);
            // 获取数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 返回数据库连接
        return conn;
    }

    /**
     * 关闭数据库连接静态方法
     *
     * @param conn 数据库连接
     */
    public static void closeConn(Connection conn) {
        if (conn != null) {
            try {
                if (!conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

LoginServlet

package net.xsp.servlet;

import net.xsp.dao.UserDao;
import net.xsp.dao.impl.UserDaoImpl;

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URLEncoder;

@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置请求对象字符编码
        request.setCharacterEncoding("utf-8");

        // 获取表单提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 创建用户数据访问对象
        UserDao userDao = new UserDaoImpl();

        //获取请求对应的会话
        HttpSession session = request.getSession();

        // 判断登录是否成功
        if (userDao.login(username, password)) {
            // 清除session里可能存在的errMsg属性
            if (session.getAttribute("errMsg") != null) {
                session.removeAttribute("errMsg");
            }
            // 采用从定向,跳转到登录成功页面
            response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username,"utf-8"));
        } else {
            // 设置session里的errMsg属性
            session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
            // 采用从定向,跳转到登录页面
            response.sendRedirect("login.jsp");
        }
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>

<html>
<head>
    <title>用户登录</title>
</head>
<body>
<h3 style="text-align: center">用户登录</h3>
<form action="login" method="post">
    <table border="1" cellpadding="10" style="margin: 0px auto">
        <tr>
            <td align="center">用户名</td>
            <td><input type="text" name="username"/></td>
        </tr>
        <tr>
            <td align="center">密&nbsp;码</td>
            <td><input type="password" name="password"/></td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </td>
        </tr>
    </table>
</form>
<%
    String errMsg = (String) session.getAttribute("errMsg");
    if (errMsg != null) {
        out.println("<p style='text-align: center; color: red'>" + new String(errMsg.getBytes("ISO-8859-1"), "utf-8") + "</p>");
    }
%>
</body>
</html>

do_login.jsp

<%@ page import="java.sql.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="net.xsp.dbutil.ConnectionManager" %>
<%@ page import="net.xsp.dao.UserDao" %>
<%@ page import="net.xsp.dao.impl.UserDaoImpl" %>
<%
    // 设置请求对象字符编码
    request.setCharacterEncoding("utf-8");

    // 获取表单提交的数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    // 创建用户数据访问对象
    UserDao userDao = new UserDaoImpl();

    // 判断登录是否成功
    if (userDao.login(username, password)) {
        // 清除session里可能存在的errMsg属性
        if (session.getAttribute("errMsg") != null) {
            session.removeAttribute("errMsg");
        }
        // 采用从定向,跳转到登录成功页面
        response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
    } else {
        // 设置session里的errMsg属性
        session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
        // 采用从定向,跳转到登录页面
        response.sendRedirect("login.jsp");
    }


    /**
     * 2
     */
//    try {
//        // 获取数据库连接
//        Connection conn = ConnectionManager.getConnection();
//        // 定义SQL字符串
//        String strSQL = "select * from t_user where username = ? and password = ?";
//        // 创建预备语句对象
//        PreparedStatement pstmt = conn.prepareStatement(strSQL);
//        // 设置占位符的值
//        pstmt.setString(1, username);
//        pstmt.setString(2, password);
//        // 执行SQL查询,返回结果集
//        ResultSet rs = pstmt.executeQuery();
//        // 判断结果集里是否有记录
//        if (rs.next()) {
//            // 清除session里可能存在的errMsg属性
//            if (session.getAttribute("errMsg") != null) {
//                session.removeAttribute("errMsg");
//            }
//            // 采用从定向,跳转到登录成功页面
//            response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
//        } else {
//            // 设置session里的errmsg属性
//                session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
//                // 采用从定向,跳转到登录页面
//                response.sendRedirect("login.jsp");
//        }
//    } catch (SQLException e) {
//        e.printStackTrace();
//    }

/**
 * 1
 */
    // 定义连接数据库的参数
//    final String DRIVER = "com.mysql.jdbc.Driver";
//    final String URL = "jdbc:mysql://localhost:3306/xspdb";
//    final String USER = "root";
//    final String PASSWORD = "1";

//    try {
//        // 安装数据库驱动程序
//        Class.forName(DRIVER);
//        // 获取数据库链接
//        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//        // 定义SQL字符串
//        String strSQL = "select * from t_user where username = ? and password = ?";
//        // 创建预备语句对象
//        PreparedStatement pstmt = conn.prepareStatement(strSQL);
//        // 设置占位符
//        pstmt.setString(1, username);
//        pstmt.setString(2, password);
//        // 执行SQL查询,返回结果集
//        ResultSet rs = pstmt.executeQuery();
//        // 判断结果集是否有记录
//        if (rs.next()) {
//            // 移除session可能存在的errMsg属性
//            session.removeAttribute("errMsg");
//            // 采用从定向,跳转到登录页面
//            response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
//        } else {
//            // 设置session里的errmsg属性
//            session.setAttribute("errMsg", "用户名或密码错误,请重新登录");
//            // 采用从定向,跳转到登录页面
//            response.sendRedirect("login.jsp");
//        }
//    } catch (ClassNotFoundException e) {
//        e.printStackTrace();
//    } catch (SQLException e) {
//        e.printStackTrace();
//    }
%>

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
    <h3><%= request.getParameter("username") %>, 登录成功!</h3>
</body>
</html>

启动tomcat服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述

状态管理

一、Cookie

会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
个性化设置(如用户自定义设置、主题等)
浏览器行为跟踪(如跟踪分析用户行为等)

创建Web项目CookieDemo
在这里插入图片描述
login.jsp页面

<%--
  Created by IntelliJ IDEA.
  User: Stranger
  Date: 2019/10/17
  Time: 8:21
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
<h3 style="text-align: center">用户登录</h3>
<form action="do_login.jsp" method="post">
    <table border="1" cellpadding="10" style="margin: 0px auto">
        <tr>
            <td align="center">用户名</td>
            <td><input id="uname" type="text" name="username"/></td>
        </tr>
        <tr>
            <td align="center">密&nbsp;码</td>
            <td><input id="upwd" type="password" name="password"/></td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <input id="saveuname" type="checkbox" name="save" value="记住用户名"/>记住用户名
                <input id="saveupwd" type="checkbox" name="save" value="记住密码" onclick="setchkuname()"/>记住密码
            </td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </td>
        </tr>
    </table>
</form>
<%
    String uname = "";
    String upwd = "";
    String saveuname = "";
    String saveupwd = "";
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie: cookies) {
        if (cookie.getName().equals("uname")) {
            uname = cookie.getValue();
        }
        if (cookie.getName().equals("upwd")) {
            upwd = cookie.getValue();
        }
        if (cookie.getName().equals("saveuname")) {
            saveuname = cookie.getValue();
        }
        if (cookie.getName().equals("saveupwd")) {
            saveupwd = cookie.getValue();
        }
    }

    String errMsg = (String) session.getAttribute("errMsg");
    if (errMsg != null) {
        errMsg = new String(errMsg.getBytes("iso-8859-1"), "utf-8");
        out.print("<script>alert('" + errMsg + "')</script>");
    }
%>
<script type="text/javascript">
    // 显示用户做出的是否记住用户名的选择
    var chkSaveUname = document.getElementById("saveuname");
    var saveuname = "<%= saveuname %>";
    if (saveuname == "yes") {
        chkSaveUname.checked = true;
    }

    // 显示用户做出的是否记住密码的选择
    var chkSaveUpwd = document.getElementById("saveupwd");
    var saveupwd = "<%= saveupwd %>";
    if (saveupwd == "yes") {
        chkSaveUpwd.checked = true;
    }

    // 根据用户做出的选择,决定是否自动填充用户名或密码
    if (chkSaveUname.checked) {
        var txtUname = document.getElementById("uname");
        txtUname.value = "<%= new String(uname.getBytes("iso-8859-1"), "utf-8") %>";
    }
    if (chkSaveUpwd.checked) {
        var txtUpwd = document.getElementById("upwd");
        txtUpwd.value = "<%= upwd %>";
    }

    /**
     * 选择【记住密码】复选框,自动会选择【记住用户名】复选框
     */
    function setchkuname() {
        if (chkSaveUpwd.checked) {
            chkSaveUname.checked = true;
        }
    }
</script>
</body>
</html>

do_login.jsp页面

<%
    // 获取表单提交的数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String[] choie = request.getParameterValues("save");

    // 判断用户是否登录成功
    if (username.equals("root") && password.equals("12345")) {
        // 创建Cookie对象
        Cookie uname = new Cookie("uname", username);
        Cookie upwd = new Cookie("upwd", password);
        Cookie saveuname = new Cookie("saveuname", "no");
        Cookie saveupwd = new Cookie("saveupwd", "no");
        if (choie != null) {
            if (choie.length == 2) {
                saveuname.setValue("yes");
                saveupwd.setValue("yes");
            } else {
                saveuname.setValue("yes");
            }
        }

        // 创建Cookie对象写入客户端
        response.addCookie(uname);
        response.addCookie(upwd);
        response.addCookie(saveuname);
        response.addCookie(saveupwd);

        session.removeAttribute("errMsg");

        // 采用重定向,跳转到登录成功页面
        response.sendRedirect("success.jsp");
    } else {
        Cookie saveuname = new Cookie("saveuname", "no");
        Cookie saveupwd = new Cookie("saveupwd", "no");
        response.addCookie(saveuname);
        response.addCookie(saveupwd);

        session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
        // 采用重定向,跳转到登录页面
        response.sendRedirect("login.jsp");
    }
%>

success.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
    <%
        String uname = "";
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie: cookies) {
            if (cookie.getName().equals("uname")) {
                uname = cookie.getValue();
            }
        }
    %>
    <h3><%= new String(uname.getBytes("iso-8859-1"), "utf-8") %>,登录成功!</h3>
</body>
</html>

启动tomcat服务器,查看运行效果
输入错误密码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、session对象

在这里插入图片描述
在这里插入图片描述
创建Web项目SessionDemo
在这里插入图片描述
User类

package net.xsp.bean;

public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

login.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3 style="text-align: center">用户登录</h3>
<form action="do_login.jsp" method="post">
    <table border="1" cellpadding="10" style="margin: 0px auto">
        <tr>
            <td align="center">用户名</td>
            <td><input type="text" name="username"/></td>
        </tr>
        <tr>
            <td align="center">密&nbsp;码</td>
            <td><input type="password" name="password"/></td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </td>
        </tr>
    </table>
</form>
<%
    String errMsg = (String) session.getAttribute("errMsg");
    if (errMsg != null) {
        // errMsg = new String(errMsg.getBytes("ISO-8859-1"), "utf-8");
        out.print("<script>alert('" + errMsg + "')</script>");
    }
%>
</body>
</html>

do_login.jsp页面

<%@ page import="net.xsp.bean.User" %>
<%@ page contentType="text/html; charset=utf-8" %>
<%
    // 设置请求对象字符编码
    request.setCharacterEncoding("utf-8");
    // 获取登录表单数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    // 判断登录是否成功
    if (username.equals("root") && password.equals("12345")) {
        // 创建用户对象
        User user = new User();
        // 设置用户对象属性
        user.setUsername(username);
        user.setPassword(password);
        // 保存登录用户信息
        session.setAttribute("LOGINED_USER", user);
        // 清除session里的errMsg属性
        if (session.getAttribute("errMsg") != null) {
            session.removeAttribute("errMsg");
        }
        // 采用重定向,跳转到首页
        response.sendRedirect("index.jsp");
    } else {
        // 在session里创建errMsg属性
        session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
        // 采用重定向,跳转到登录页面
        response.sendRedirect("login.jsp");
    }
%>

add_news.jsp页面

<%@ page import="net.xsp.bean.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>添加新闻</title>
</head>
<body>
    <%-- 利用session实现登录验证 --%>
    <%
        User user = (User) session.getAttribute("LOGINED_USER");
        if (user == null) {
            // 在session里面创建errMsg属性
            session.setAttribute("errMsg", "要访问添加新闻页面,请先登录!");
            // 从定向跳转
            response.sendRedirect("login.jsp");
        } else {
            // 删除session里的errMsg属性
            if (session.getAttribute("errMsg") != null) {
                session.removeAttribute("errMsg");
            }
        }
    %>
    <h3>添加新闻</h3>
    此页面还在建设中......
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在浏览器地址栏里输入添加新闻页面网址,然后敲回车确认:
在这里插入图片描述
在这里插入图片描述
重启服务器,直接访问http://localhost:8080/SessionDemo//add_news.jsp:
在这里插入图片描述
在这里插入图片描述

三、application对象

void setAttribute(String key, Object value):以键/值的方式,将一个对象的值存放到application中
Object getAttribute(String key):根据键去获取application中存放对象的值

创建Web项目ApplicationDemo
在这里插入图片描述
User类

package net.xsp.bean;

/**
 * Created by xsping on 2019/10/17
 */
public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object obj) {
        return username.equals(((User) obj).getUsername())
                && password.equals(((User) obj).getPassword());
    }
}

UserDao接口

package net.xsp.dao;

/**
 * 功能:用户数据访问接口
 * 作者:
 * 日期:2019年10月24日
 */
public interface UserDao {
    /**
     * 登录方法
     *
     * @param username
     * @param password
     * @return
     */
    boolean login(String username, String password);
}

用户数据访问接口实现类UserDaoImpl

package net.xsp.dao.impl;

import net.xsp.dao.UserDao;
import net.xsp.dbutil.ConnectionManager;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 功能:用户数据访问接口实现类
 * 作者:
 * 日期:2019年10月24日
 */
public class UserDaoImpl implements UserDao {
    @Override
    public boolean login(String username, String password) {
        // 定义标识变量
        boolean flag = false;

        // 获取数据库连接
        Connection conn = ConnectionManager.getConnection();
        // 定义SQL字符串
        String strSQL = "select * from t_user where username = ? and password = ?";
        try {
            // 创建预备语句对象
            PreparedStatement pstmt = conn.prepareStatement(strSQL);
            // 设置占位符的值
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            // 执行SQL查询,返回结果集
            ResultSet rs = pstmt.executeQuery();
            // 判断结果集里是否有记录
            if (rs.next()) {
                flag = true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            ConnectionManager.closeConn(conn);
        }

        // 返回标识变量
        return flag;
    }
}

数据库连接管理类

package net.xsp.dbutil;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * 功能:数据库连接管理类
 * 作者:
 * 日期:2019年10月24日
 */
public class ConnectionManager {
    // 定义连接数据库的参数值
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/xspdb";
    private static final String USER = "root";
    private static final String PASSWORD = "1";

    /**
     * 私有化构造方法,拒绝实例化
     */
    private ConnectionManager() {
    }

    /**
     * 获取数据库连接静态方法
     *
     * @return 数据库连接
     */
    public static Connection getConnection() {
        // 声明数据库连接
        Connection conn = null;

        try {
            // 安装数据库驱动程序
            Class.forName(DRIVER);
            // 获取数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 返回数据库连接
        return conn;
    }

    /**
     * 关闭数据库连接静态方法
     *
     * @param conn 数据库连接
     */
    public static void closeConn(Connection conn) {
        if (conn != null) {
            try {
                if (!conn.isClosed()) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

login.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
<h3 style="text-align: center">用户登录</h3>
<form action="do_login.jsp" method="post">
    <table border="1" cellpadding="10" style="margin: 0px auto">
        <tr>
            <td align="center">用户名</td>
            <td><input type="text" name="username"/></td>
        </tr>
        <tr>
            <td align="center">密&nbsp;码</td>
            <td><input type="password" name="password"/></td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <input type="submit" value="登录"/>
                <input type="reset" value="重置"/>
            </td>
        </tr>
    </table>
</form>
<%
    String errMsg = (String) session.getAttribute("errMsg");
    if (errMsg != null) {
        out.println("<script>alert('" + errMsg + "')</script>");
        //out.println("<p style='text-align: center; color: red'>" + new String(errMsg.getBytes("ISO-8859-1"), "utf-8") + "</p>");
    }
%>
</body>
</html>

do_login.jsp页面

<%@ page import="net.xsp.dao.UserDao" %>
<%@ page import="net.xsp.dao.impl.UserDaoImpl" %>
<%@ page import="net.xsp.bean.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    // 设置请求对象字符编码
    request.setCharacterEncoding("utf-8");
    // 获取登录表单提交的数据
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    // 创建用户数据访问对象
    UserDao userDao = new UserDaoImpl();
    // 判断用户是否登录成功
    if (userDao.login(username, password)) {
        // 创建登录用户对象
        User loginedUser = new User();
        // 设置用户对象属性
        loginedUser.setUsername(username);
        loginedUser.setPassword(password);
        // 创建登录用户列表对象
        List<User> loginedUsers = new ArrayList<>();
        // 判断application里是否有登录用户列表属性
        if (application.getAttribute("LOGINED_USERS") == null) {
            // 在application里添加登录用户列表属性
            application.setAttribute("LOGINED_USERS", loginedUsers);
        }  else {
            // 从application里获取登录用户列表
            loginedUsers = (List<User>) application.getAttribute("LOGINED_USERS");
        }
        // 将当前登录成功的用户添加到登录用户列表里
        loginedUsers.add(loginedUser);
        // 更新application里登录用户列表属性值
        application.setAttribute("LOGINED_USERS", loginedUsers);
        // 清除session里errMsg属性
        if (session.getAttribute("errMsg") != null) {
            session.removeAttribute("errMsg");
        }
        // 采用重定向,跳转到登录成功页面
        response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
    } else {
        // 创建session属性errMsg
        session.setAttribute("errMsg", "用户名或密码错误,请重新登录!");
        // 采用重定向,跳转到登录页面
        response.sendRedirect("login.jsp");
    }
%>

success.jsp页面

<%@ page import="net.xsp.bean.User" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录成功</title>
</head>
<body>
    <h3><%= request.getParameter("username") %>,登录成功!</h3>
    <%
        // 从application里获取登录列表
        List<User> loginedUsers = (List<User>) application.getAttribute("LOGINED_USERS");
    %>
    目前,已有<%= loginedUsers.size() %>人访问过本网站。
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述

数据源和JavaBean

一、JNDI概述

JNDI(Java Naming and Directory Interface),Java命名与目录接口,是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。

JNDI可以把Java应用程序访问数据库管理和配置交给存放Java应用的服务器,比如tomcat服务器。在没有JNDI之前,JDBC连接数据库,Java应用程序与MySQL提供的驱动程序关联,映射一个Driver的Class对象(com.mysql.jdbc.Driver),然后用Java提供的DriverMannager管理类调用getConnection(“jdbc:mysql://localhost:8080/数据库名字”, “用户名”, “密码”)方法获得一个Connection连接对象,让Java与指定数据库建立连接。缺点很明显:当所有程序调试完成后,所有Java源文件形成Jar包,如果数据库类型或用户名改变,就必须改源代码。有JNDI之后,把变化的地方交给服务器来设置一个数据源,需要JDBC建立连接时引用,交给服务器管理配置,Java应用程序需要就到数据库连接池里去拿一个。

二、数据库连接池技术

数据库连接池技术是一种提升应用程序性能的技术,核心作用是管理是连接到数据库的多个连接的打开和释放,即形成连接池管理。应用程序需要连接时使用它,使用完毕后又将其放回连接池中。当应用程序需要连接时,就绪连接一直保持可用状态。池管管理数据库连接的生命周期,这样开发人员实际上不需要等待连接建立,或者手动关闭连接。连接池机制节省昂贵的操作及资源消耗,方便了应用程序运行时建立网络连接,并最终在后端初始化数据库会话。

创建Web项目DataSourceDemo
在这里插入图片描述
栏目实体类Topic

package net.xsp.bean;

/**
 * 功能:栏目实体类
 * 作者:
 * 日期:2019年11月7日
 */
public class Topic {

    private int tid;
    private String tname;

    public int getTid() {
        return tid;
    }

    public void setTid(int tid) {
        this.tid = tid;
    }

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }

    @Override
    public String toString() {
        return "Topic{" +
                "tid=" + tid +
                ", tname='" + tname + '\'' +
                '}';
    }
}

栏目数据访问类TopicDao

package net.xsp.dao;

import net.xsp.bean.Topic;
import net.xsp.dbutil.ConnectionManager;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * 功能:栏目数据访问类
 * 作者:
 * 日期:2019年11月7日
 */
public class TopicDao {

    /**
     * 查询全部栏目
     *
     * @return 全部栏目构成的列表
     */
    public List<Topic> findAllTopics() {

        // 定义栏目列表
        List<Topic> topics = new ArrayList<>();

        try {
            // 获取数据库连接
            Connection conn = ConnectionManager.getConnection();
            // 定义SQL字符串
            String strSQL = "select * from topic";
            // 创建语句对象
            Statement stmt =conn.createStatement();
            // 执行SQL查询,返回结果集
            ResultSet rs = stmt.executeQuery(strSQL);
            // 遍历结果集
            while (rs.next()) {
                // 创建栏目实体
                Topic topic =new Topic();
                // 利用当前记录字段值设置栏目属性值
                topic.setTid(rs.getInt("tid"));
                topic.setTname(rs.getString("tname"));
                // 将栏目实体添加到栏目列表
                topics.add(topic);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 返回栏目列表
        return topics;
    }
}

数据库连接管理类ConnectionManager

package net.xsp.dbutil;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 功能:数据库连接管理器
 * 作者:
 * 日期:2019年11月7日
 */
public class ConnectionManager {

    /**
     * 私有化构造方法,拒接实例化
     */
    private ConnectionManager() {
    }

    /**
     * 获取数据库连接静态方法
     *
     * @return 数据库连接
     */
    public static Connection getConnection() {

        // 定义数据库连接
        Connection conn = null;

        try {
            // 初始化上下文
            Context ctx = new InitialContext();
            // 在数据库连接池查询获取数据源
            DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/news");
            // 通过数据源获取数据库连接
            conn = ds.getConnection();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 返回数据库连接
        return conn;
    }

    public static void main(String[] args) {
        Connection conn = getConnection();
        if (conn != null) {
            System.out.println("恭喜,数据库连接成功!");
        } else {
            System.out.println("遗憾,数据库连接失败!");
        }
    }
}

context.xml

<?xml version="1.0" encoding="utf-8" ?>
<Context>
    <Resource
        name="jdbc/news" auth="Container"
        type="javax.sql.DataSource"
        maxActive="100" maxIdle="30" maxWait="10000"
        driverClassName="com.mysql.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/news"
        username="root" password="1"
    />
</Context>

topic_list.jsp页面

<%@ page import="java.sql.Connection" %>
<%@ page import="net.xsp.dbutil.ConnectionManager" %>
<%@ page import="java.sql.Statement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新闻栏目列表</title>
</head>
<body>
    <%
        // 获取数据库连接
        Connection conn = ConnectionManager.getConnection();
        // 定义SQL字符串
        String strSQL = "select * from topic";
        // 创建语句对象
        Statement stmt = conn.createStatement();
        // 执行SQL查询,返回结果集
        ResultSet rs = stmt.executeQuery(strSQL);
        out.println("<table border='1' cellpadding='10'>" +
                "<tr><td width='50' align='center'><b>编号</b></td width='50' align='center'><td><b>栏目</b></td></tr>");
        // 遍历结果集,分行显示在页面
        while (rs.next()) {
            out.println("<tr><td align='center'>" + rs.getInt("tid") + "</td><td align='center'>" + rs.getString("tname") + "</td></tr>");
        }
        out.println("</table>");
    %>
</body>
</html>

topic_list_new.jsp页面

<%@ page import="net.xsp.dao.TopicDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.bean.Topic" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>新闻栏目列表</title>
</head>
<body>
    <%
        // 创建栏目数据访问对象
        TopicDao topicDao = new TopicDao();
        // 获取全部栏目列表
        List<Topic> topics = topicDao.findAllTopics();

        out.println("<table border='1' cellpadding='10'>" +
                "<tr><td width='50' align='center'><b>编号</b></td width='50' align='center'><td><b>栏目</b></td></tr>");
        // 遍历栏目列表,分行显示在页面
        for (Topic topic: topics) {
            out.println("<tr><td align='center'>" + topic.getTid()
                    + "</td><td align='center'>" + topic.getTname() + "</td></tr>");
        }
        out.println("</table>");
    %>
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述

三、组件开发与JavaBean

1、组件化思想

组件化思想其实就是分而治之(最重要的架构思想),页面逻辑过于复杂,便将页面分为很多个业务组件模块分而治之,这样维护人员每次只需要改动对应的模块即可,以达到最大程度地降低开发难度与维护成本的效果,所以现在比较好的框架都会对组件化作一定程度的实现。

2、JavaBean的概念

JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性。众所周知,属性名称符合这种模式,其他Java 类可以通过自身机制发现和操作这些JavaBean 属性。 换句话说,JavaBean就是一个Java的类,只不过这个类你要按上面提到的一些规则来写,比如方法必须是公共的,无参构造等等,按这些规则写了之后,这个JavaBean可以在程序里被方便地重用,使开发效率提高。

3、采用JavaBean的优势

解决代码重复编写,减少代码冗余
功能区分明确,避免业务逻辑处理与页面显示处理集中在一起造成混乱
提高了代码的维护性

启动服务器,访问topic_list_new.jsp页面:
在这里插入图片描述

分页技术

一、软分页

通过代码实现分页,将全部表记录以实体方式存放到ArrayList或Vector对象里,从ArrayList或Vector对象里去获取当前页要显示的实体集,此方法效率很低。

二、硬分页

通过数据库实现分页。不同数据库分页方式不同。

三、创建Web项目PagingNews

在这里插入图片描述
在这里插入图片描述
News

package net.xsp.news.bean;

import java.sql.Timestamp;

/**
 * 功能:新闻实体类
 * 作者:
 * 日期:2019年11月14日
 */
public class News {
    private int nid;
    private int ntid;
    private String ntname;
    private String ntitle;
    private String nauthor;
    private Timestamp ncreatedate;
    private String npicpath;
    private String ncontent;
    private Timestamp nmodifydate;
    private String nsummary;

    public int getNid() {
        return nid;
    }

    public void setNid(int nid) {
        this.nid = nid;
    }

    public int getNtid() {
        return ntid;
    }

    public void setNtid(int ntid) {
        this.ntid = ntid;
    }

    public String getNtname() {
        return ntname;
    }

    public void setNtname(String ntname) {
        this.ntname = ntname;
    }

    public String getNtitle() {
        return ntitle;
    }

    public void setNtitle(String ntitle) {
        this.ntitle = ntitle;
    }

    public String getNauthor() {
        return nauthor;
    }

    public void setNauthor(String nauthor) {
        this.nauthor = nauthor;
    }

    public Timestamp getNcreatedate() {
        return ncreatedate;
    }

    public void setNcreatedate(Timestamp ncreatedate) {
        this.ncreatedate = ncreatedate;
    }

    public String getNpicpath() {
        return npicpath;
    }

    public void setNpicpath(String npicpath) {
        this.npicpath = npicpath;
    }

    public String getNcontent() {
        return ncontent;
    }

    public void setNcontent(String ncontent) {
        this.ncontent = ncontent;
    }

    public Timestamp getNmodifydate() {
        return nmodifydate;
    }

    public void setNmodifydate(Timestamp nmodifydate) {
        this.nmodifydate = nmodifydate;
    }

    public String getNsummary() {
        return nsummary;
    }

    public void setNsummary(String nsummary) {
        this.nsummary = nsummary;
    }

    @Override
    public String toString() {
        return "News{" +
                "nid=" + nid +
                ", ntid=" + ntid +
                ", ntname='" + ntname + '\'' +
                ", ntitle='" + ntitle + '\'' +
                ", nauthor='" + nauthor + '\'' +
                ", ncreatedate=" + ncreatedate +
                ", npicpath='" + npicpath + '\'' +
                ", ncontent='" + ncontent + '\'' +
                ", nmodifydate=" + nmodifydate +
                ", nsummary='" + nsummary + '\'' +
                '}';
    }
}

NewsDao

package net.xsp.news.dao;

import net.xsp.news.bean.News;
import net.xsp.news.dbutil.ConnectionManager;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 功能:新闻数据访问类
 * 作者:
 * 日期:2019年11月14日
 */
public class NewsDao {

    /**
     * 获取全部新闻列表
     *
     * @return 全部新闻列表
     */
    public List<News> findAllNews() {

        // 定义新闻列表
        List<News> newsList = new ArrayList<>();

        // 获取数据库连接
        Connection conn = ConnectionManager.getConnection();
        // 定义SQL字符串
        String strSQL = "select * from news";
        try {
            // 创建语句对象
            Statement stmt = conn.createStatement();
            // 执行SQL查询,返回结果集
            ResultSet rs = stmt.executeQuery(strSQL);
            // 遍历结果集
            while (rs.next()) {

                // 创建新闻实体对象
                News news = new News();
                // 将当前记录字段值去设置新闻实体属性
                news.setNid(rs.getInt("nid"));
                news.setNtid(rs.getInt("ntid"));
                news.setNtitle(rs.getString("ntitle"));
                news.setNauthor(rs.getString("nauthor"));
                news.setNcreatedate(rs.getTimestamp("ncreatedate"));
                news.setNpicpath(rs.getString("npicpath"));
                news.setNcontent(rs.getString("ncontent"));
                news.setNmodifydate(rs.getTimestamp("nmodifydate"));
                news.setNsummary(rs.getString("nsummary"));
                // 将当前新闻实体添加到新闻列表
                newsList.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 关闭数据库连接
            ConnectionManager.closeConn(conn);
        }

        // 返回新闻列表
        return newsList;
    }

    /**
     * 获取总记录数
     *
     * @return 总记录数
     */
    public int getCount() {

        // 返回总记录数
        return findAllNews().size();

    }

    /**
     * 获取总页数
     *
     * @param count 总记录数
     * @param pageSize 每页记录数
     * @return 总页数
     */
    public int getTotalPages(int count, int pageSize) {

        // 返回总页数
        return count % pageSize == 0 ? count / pageSize : count /pageSize + 1;
    }

    /**
     * 按页获取新闻列表
     *
     * @param pageIndex 当前页码
     * @param pageSize 每页记录数
     * @return 当前页新闻列表
     */
    public List<News> findNewsByPage(int pageIndex, int pageSize) {

        // 定义新闻列表
        List<News> newsList = new ArrayList<>();

        // 获取数据库连接
        Connection conn = ConnectionManager.getConnection();
        // 定义SQL字符串
        String strSQL = "select * from news limit ?, ?";
        try {
            // 创建预备语句对象
            PreparedStatement pstmt = conn.prepareStatement(strSQL);
            // 设置占位符的值
            pstmt.setInt(1, pageSize * (pageIndex - 1));
            pstmt.setInt(2, pageSize);
            // 执行SQL查询,返回结果集
            ResultSet rs = pstmt.executeQuery();
            // 遍历结果集
            while (rs.next()) {

                // 创建新闻实体对象
                News news = new News();
                // 将当前记录字段值去设置新闻实体属性
                news.setNid(rs.getInt("nid"));
                news.setNtid(rs.getInt("ntid"));
                news.setNtitle(rs.getString("ntitle"));
                news.setNauthor(rs.getString("nauthor"));
                news.setNcreatedate(rs.getTimestamp("ncreatedate"));
                news.setNpicpath(rs.getString("npicpath"));
                news.setNcontent(rs.getString("ncontent"));
                news.setNmodifydate(rs.getTimestamp("nmodifydate"));
                news.setNsummary(rs.getString("nsummary"));
                // 将当前新闻实体添加到新闻列表
                newsList.add(news);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            ConnectionManager.closeConn(conn);
        }

        // 返回新闻列表
        return newsList;

    }
}

ConnectionManager

package net.xsp.news.dbutil;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 功能:数据库连接管理类
 * 作者:
 * 日期:2019年11月14日
 */
public class ConnectionManager {
    /**
     * 私有化构造方法,拒绝实例化
     */
    private ConnectionManager() {
    }

    /**
     * 获取数据库连接静态方法
     *
     * @return 数据库连接
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            // 创建初始化上下文
            Context ctx = new InitialContext();
            // 通过数据库连接池查询获取数据源
            DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/news");
            // 通过数据源获取数据库连接
            conn = ds.getConnection();
        } catch (NamingException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 关闭数据库连接静态方法
     *
     * @param conn 数据库连接
     */
    public static void closeConn(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

context.xml

<?xml version="1.0" encoding="utf-8" ?>
<Context>
    <Resource
            name="jdbc/news" auth="Container"
            type="javax.sql.DataSource"
            maxAlive="100" maxIdle="30" maxWait="10000"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/news"
            username="root" password="1"/>
</Context>

allnews.jsp

<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>不分页显示全部新闻列表</title>
</head>
<body>
    <%
        // 创建新闻数据访问对象
        NewsDao newsDao = new NewsDao();
        // 获取全部新闻列表
        List<News> newsList = newsDao.findAllNews();
        // 在页面上显示数据
        out.print("<table border='1' cellpadding='10'>");
        out.print("<tr><th>编号</th><th>标题</th><th>创建时间</th></tr>");
        // 遍历新闻列表
        for (News news: newsList) {

            out.print("<tr><td>" + news.getNid() + "</td>");
            out.print("<td>" + news.getNtitle() + "</td>");
            out.print("<td>" + news.getNcreatedate() + "</td></tr>");
        }

        out.print("</table>");
    %>
</body>
</html>

pagingnews.jsp

<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="java.util.List" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>分页显示全部新闻列表</title>
</head>
<body>
    <%
        // 创建新闻数据访问对象
        NewsDao newsDao = new NewsDao();

        // 获取总记录数
        int count = newsDao.getCount();
        // 定义每页最大记录数
        int pageSize = 5;
        // 获取总页数
        int totalPages = newsDao.getTotalPages(count, pageSize);

        // 获取当前页码
        String currentPage = request.getParameter("pageIndex");
        // 首次进去页面,应该显示第一页内容
        if (currentPage == null) {
            currentPage = "1";
        }
        // 获取页索引
        int pageIndex = Integer.parseInt(currentPage);
        // 对首页与末页的页索引进行控制
        if (pageIndex < 1) {
            pageIndex = 1;
        } else if (pageIndex > totalPages) {
            pageIndex = totalPages;
        }

        // 获取当前页新闻列表
        List<News> newsList = newsDao.findNewsByPage(pageIndex, pageSize);
        // 在页面上显示数据
        out.print("<table border='1' cellpadding='10' style='margin:0px auto'>");
        out.print("<tr><th>编号</th><th>标题</th><th>创建时间</th></tr>");
        // 遍历新闻列表
        for (News news: newsList) {

            out.print("<tr><td>" + news.getNid() + "</td>");
            out.print("<td>" + news.getNtitle() + "</td>");
            out.print("<td>" + news.getNcreatedate() + "</td></tr>");
        }

        out.print("</table>");
    %>
    <%-- 实现分页操作【首页、上一页、下一页、末页】 --%>
    <p style="text-align: center">
        <a href="pagingnews.jsp?pageIndex=1">[首页]</a>&nbsp;&nbsp;
        <a href="pagingnews.jsp?pageIndex=<%= pageIndex - 1 %>">[上一页]</a>&nbsp;&nbsp;
        <a href="pagingnews.jsp?pageIndex=<%= pageIndex + 1 %>">[下一页]</a>&nbsp;&nbsp;
        <a href="pagingnews.jsp?pageIndex=<%= totalPages %>">[末页]</a>&nbsp;&nbsp;
        <%= pageIndex %> / <%= totalPages %>
    </p>
</body>
</html>

softpagingnews.jsp

<%@ page import="net.xsp.news.dao.NewsDao" %>
<%@ page import="net.xsp.news.bean.News" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>软分页显示新闻列表</title>
</head>
<body>
    <%
        // 获取总页数
        NewsDao newsDao = new NewsDao();
        int count = newsDao.getCount();
        int pageSize = 5;
        int totalPages = newsDao.getTotalPages(count, pageSize);
        List<News> allnews = newsDao.findAllNews();

        // 获取当前页码
        String currentPage = request.getParameter("pageIndex");
        if (currentPage == null) {
            currentPage = "1";
        }
        int pageIndex = Integer.parseInt(currentPage);
        // 对首页与末页进行控制
        if (pageIndex < 1) {
            pageIndex = 1;
        } else if (pageIndex > totalPages) {
            pageIndex = totalPages;
        }

        // 生成当前页的新闻列表
        List<News> newsList = new ArrayList<>();
        for (int i = (pageIndex - 1) * pageSize; i <pageIndex * pageSize; i++) {
            if (i < count) {
                newsList.add(allnews.get(i));
            }
        }

        out.print("<table border='1' cellpadding='10' style='margin: 0px auto'>");
        out.print("<tr><th>编号</th><th>标题</th><th>创建时间</th></tr>");
        for (News news : newsList) {
            out.print("<tr><td>" + news.getNid() + "</td>");
            out.print("<td>" + news.getNtitle() + "</td>");
            out.print("<td>" + news.getNcreatedate() + "</td></tr>");
        }
        out.print("</table>");
    %>

    <p style="text-align: center">
        <a href="softpagingnews.jsp?pageIndex=1">[首页]</a>&nbsp;&nbsp;
        <a href="softpagingnews.jsp?pageIndex=<%= pageIndex - 1 %>">[上一页]</a>&nbsp;&nbsp;
        <a href="softpagingnews.jsp?pageIndex=<%= pageIndex + 1 %>">[下一页]</a>&nbsp;&nbsp;
        <a href="softpagingnews.jsp?pageIndex=<%= totalPages %>">[末页]</a>&nbsp;&nbsp;
        <%= pageIndex %> / <%= totalPages %>
    </p>
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件上传与下载

一、SmartUpload组件

SmartUpload是专门用于实现文件上传及下载的免费组件。

使用简单,编写少量代码,完成上传下载功能
能够控制上传内容
能够控制上传文件的大小、类型

SmartUpload目前已停止更新服务。

创建Web项目SmartUploadDemo
在这里插入图片描述
upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>利用SmartUpload组件上传文件</title>
</head>
<body>
    <form action="do_upload.jsp" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="name" />
        照片:<input type="file" name="photo" />
        <input type="submit" value="上传" />
    </form>
</body>
</html>

do_upload.jsp

<%@ page import="com.jspsmart.upload.SmartUpload" %>
<%@ page import="com.jspsmart.upload.File" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>显示上传数据</title>
</head>
<body>
    <%!
        // 声明文件名及扩展名  全局声明
        String filename, ext;
    %>
    <%
        // 实例化上传组件
        SmartUpload su = new SmartUpload();
        // 初始化上传,绑定页面
        su.initialize(pageContext);
        // 判断文件类型是否符合要求
        try {
            // 设置上传文件允许类型
            su.setAllowedFilesList("jpg, gif, png, bmp");
            // 上传文件
            su.upload();
        } catch (Exception e) {
            // 弹出消息框告知用户,并且跳转到上传页面
            out.print("<script type='text/javascript'>" +
                      "   alert('只能上传jpg, gif, png或bmp文件!');" +
                      "   window.location = 'upload.html';" +
                      "</script>");
        }

        // 获取第一个上传文件
        File file = su.getFiles().getFile(0);
        // 判断文件上传是否发生丢失现象
        if (file.isMissing()) {
            // 弹出消息框告知用户,并且跳转到上传页面
            out.print("<script type='text/javascript'>" +
                    "   alert('上传文件失败,请再次选择文件上传!');" +
                    "   window.location = 'upload.html';" +
                    "</script>");
        } else {
            // 定义上传文件的最大尺寸(单位:字节)
            long FILE_MAX_SIZE = 400000;
            // 判断上传文件大小是否符合要求
            if (file.getSize() <= FILE_MAX_SIZE) {
                // 获取上传文件名(包含扩展名)
                filename = file.getFileName();
                // 获取上传文件的扩展名
                ext = file.getFileExt();
                // 去掉扩展名
                filename = filename.substring(0, filename.lastIndexOf("."));
                // 对文件名进行utf-8转码
                filename = new String(filename.getBytes(), "utf-8");
                // 利用时间戳与随机整数修改文件名
                filename = filename + String.valueOf(System.currentTimeMillis()) +
                        String.valueOf((int) (Math.random() * 900) + 100);
                // 获取应用程序的真实路径(物理路径)
                String realPath = application.getRealPath("/");
                // 创建上传文件的url
                String url = realPath + "upload\\" + filename + "." + ext;
                // 将上传文件保存到服务器指定位置
                file.saveAs(url, SmartUpload.SAVE_PHYSICAL);
                // 提示用户上传成功
                out.print("文件上传成功!<br/>");
                out.print("保存位置:" + url + "<br/>");
            } else {
                // 弹出消息框告知用户,并且跳转到上传页面
                out.print("<script type='text/javascript'>" +
                        "   alert('上传文件太大,上传失败!');" +
                        "   window.location = 'upload.html';" +
                        "</script>");
            }
        }
        // 获取表单提交的姓名数据
        String name = su.getRequest().getParameter("name");
        // 对姓名数据进行utf-8转码
        name = new String(name.getBytes(), "utf-8");
    %>
    姓名:<%= name %><br/>
    照片:<br />
    <img src="upload/<%= filename %>.<%= ext %>" width="300" height="250">
</body>
</html>

download.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下载文件</title>
</head>
<body>
    单击下载文件:<a href="do_download.jsp?filename=scenery.jpg">scenery.jpg</a>
</body>
</html>

do_download.jsp

<%@ page import="com.jspsmart.upload.SmartUpload" %>
<%
    // 获取下载文件名
    String filename = request.getParameter("filename");
    // 创建SmartUpload实例
    SmartUpload su = new SmartUpload();
    // 让SmartUpload实例初始化
    su.initialize(pageContext);
    // 禁止浏览器自动打开文件
    su.setContentDisposition(null);
    // 利用SmartUpload组件下载文件
    su.downloadFile("/upload/" + filename);
%>

启动服务器,运行
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、FileUpload组件

上传的文件要求包括一个根据RFC 1867(在HTML中基于表单的文件)编码的选项列表清单。组件FileUpload可以解析这个请求,并给你的应用程序提供一份独立上传的项目清单。无论每个项目背后如何执行都实现了FileItem接口。

这里将描述组件FileUpload库的普通API,这些API比较简单。不过,对于最终的实现,你可以参考最新的API流。

每一个文件项目都有一些属性,这些可能在你的应用程序中应用到。比如:每一个项目有一个名称name和内容类型content type,并提供了一个 InputStream访问其数据。另一方面,你处理项目的方法可能有所不同,这个依赖于是否这个项目是一个规则的表单域,即这个数据是来自普通的表单文本,还是普通的HTML域或是一个上传文件。在FileItem接口中提供了处理这些问题的方法,可以更加方便的去访问这些数据。

组件FileUpload使用FileItemFactory工厂创建新的文件项目。这个给了组件FileUpload很大的灵活性。这个工厂拥有怎样创建项目的最终控制权。工厂执行过程中上传项目文件的临时数据可以存储在内存中或硬盘上。这个依赖于上传项目的大小(即:数据的字节)。不过这种行为可以在你的应用程序中适当的自定制。

Servlet基础

一、Servlet任务

读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。

读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。

处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。

发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。

发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

二、Servlet相关接口与抽象类

ServeltConfig接口:在Servlet初始化过程中获取配置信息,一个Servlet只有一个ServletConfig对象
ServeltContext接口:获取Servlet上下文
GenericServlet抽象类:提供了Servlet与ServletConfig接口的默认实现方法

三、HttpServlet类

HttpServlet继承于GenericServlet
处理HTTP协议的请求和响应,使用doXxx()接收用户请求
doGet():用户使用get方式提交请求时调用
doPost():用户使用post方式提交请求时调用

四、Serlvet配置

从Servlet3.0开始,配置Servlet支持注解方式,但还是保留了配置web.xml方式。

web.xml文件中配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>HelloServletWorld</servlet-name>
        <servlet-class>net.xsp.servlet.HelloServletWorld</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>xsping</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServletWorld</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

五、创建Web项目HelloServletWorld

在这里插入图片描述
基于Servlet模板创建HelloServletWorld类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package net.xsp.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;


@WebServlet(name = "HelloServletWorld",
        value = "/hello",
        initParams = {
            @WebInitParam(name = "username", value = "xsping")
        },
        loadOnStartup = 1)
public class HelloServletWorld extends HttpServlet {

    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("初始化Servlet。。。");
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象字符编码格式
        response.setCharacterEncoding("utf-8");
        // 获取初始化参数值
        String username = getInitParameter("username");
        // 获取打印输入流
        PrintWriter out = response.getWriter();
        // 创建简单日期格式对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
        out.print("<html>" +
                    "<head>" +
                        "<meta charset='UTF-8'>" +
                        "<title>亲切的问候</title>" +
                    "<head>" +
                    "<body>" +
                        "<h3>亲爱的" + username + ", 欢迎访问Servlet世界~</h3>" +
                        "<h3>当前时间:" + sdf.format(new Date()) + "</h3>" +
                    "</body>" +
                    "/html>"
        );
    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("销毁Servlet。。。");
    }
}

上述注解符@WebServlet的配置,相当于在web.xml里做了如下配置:
在这里插入图片描述
启动服务器,访问http://localhost:8080/HelloServletWorld/hello
在这里插入图片描述

六、创建Web项目LoginDemo02

在这里插入图片描述
在src里创建包net.hw.servlet,在里面创建登录处理程序LoginServlet

package net.xsp.servlet;

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.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;

@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 设置请求对象字符编码格斯
        request.setCharacterEncoding("utf-8");
        // 获取登录表单数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println(username);
        // 判断登录是否成功
        if (username.equals("张三丰") && password.equals("12345")) {
            // 采用从定向,跳转到登录成功页面
            response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
        } else {
            // 采用从定向,跳转到登录失败页面
            response.sendRedirect("success.jsp?username=" + URLEncoder.encode(username, "utf-8"));
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

拷贝其他项目的登录、登陆成功、登录失败页面
在这里插入图片描述
启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

JSTL与EL

一、EL的语法

${ EL exprission }
${ bean.name } 或 b e a n [ ′ n a m e ′ ] , { bean['name'] }, bean[name]{bean.name}实质是调用bean的getName()方法

[ ]或 . 运算符获取对象属性、获取对象集合中的数据
例如,在Session中保存了一个(list)集合users,${sessionScope.user[1]}

二、EL的特点

自动转换类型
EL得到某个数据时可以自动转换类型
对于类型的限制更加宽松
使用简单
相比较在JSP中嵌入Java代码,EL应用更简单

三、创建Web项目JSTLELDemo

在web目录里创建演示页面demo01.jsp
在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: Stranger
  Date: 2019/12/30
  Time: 19:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL演示01</title>
</head>
<body>
    <%
        String username = "李元霸";
        pageContext.setAttribute("username", "张三丰");
        request.setAttribute("username", "李世民");
        session.setAttribute("username", "郑晓雯");
        application.setAttribute("username", "唐雨涵");
    %>
    利用JSP表达式输出变量值:<br/>
    姓名:<%= username %><br/>
    姓名:<%= pageContext.getAttribute("username")%><br/>
    姓名:<%= request.getAttribute("username")%><br/>
    姓名:<%= session.getAttribute("username")%><br/>
    姓名:<%= application.getAttribute("username")%><br/>
    利用EL表达式输出变量值:<br/>
    姓名:${username}<br/>
    姓名:${pageScope.username}<br/>
    姓名:${requestScope.username}<br/>
    姓名:${sessionScope.username}<br/>
    姓名:${applicationScope['username']}<br/>
</body>
</html>

启动服务器,访问http://localhost:8080/JSTLELDemo/demo01.jsp:
在这里插入图片描述${username} 不能访问在JSP脚本里定义的变量username,而是与${pageScope.username}一样的作用,访问pageContext里的属性值。

在web目录里创建演示页面demo02.jsp
在这里插入图片描述

<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %><%--
  Created by IntelliJ IDEA.
  User: Stranger
  Date: 2019/12/30
  Time: 19:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL演示02</title>
</head>
<body>
    <%
        Map<String, String> names = new HashMap<>();
        names.put("one", "李玉文");
        names.put("two", "钟发奎");
        names.put("three", "周晓雯");
        session.setAttribute("names", names);
    %>
    第一个学生:<%= names.get("one") %> : ${sessionScope.names.one} : ${names['one']}<br/>
    第二个学生:<%= names.get("two") %> : ${sessionScope.names.two} : ${names['two']}<br/>
    第三个学生:<%= names.get("three") %> : ${sessionScope.names.three} : ${names['three']}<br/>
</body>
</html>

启动服务器,访问http://localhost:8080/JSTLELDemo/demo02.jsp:
在这里插入图片描述
在WEB-INF目录里创建lib子目录,添加标准标签库jar包
在这里插入图片描述
在web目录里创建演示页面demo03.jsp
在这里插入图片描述

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>EL演示03</title>
</head>
<body>
<c:set var="x" value="${1+2+3}" scope="session"/>
<%
    String y = String.valueOf(1 + 2 + 3);
    session.setAttribute("y", y);
%>

x: <c:out value="${x}"/><br/>
y: <c:out value="${y}"/> <br/>

<c:remove var="y" scope="session"/>
y: ${sessionScope.y}<br/>  <!-- y已被删除,因此没有值可以显示 -->

<hr>
if标签用法示例(单分支结构) <br/>
<c:if test="${x=='6' }" var="result">
    x的结果是6。<br/>
</c:if>
条件判断的结果为:${result}<br/>

<hr>
choose、when、otherwise标签用法示例(多分支结构)<br/>
<%
    Random rnd = new Random();
    Integer luck = new Integer(rnd.nextInt(10));
    request.setAttribute("luck", luck);
%>
<c:choose>
    <c:when test="${luck==8}">恭喜你中了一等奖!</c:when>
    <c:when test="${luck==6}">恭喜你中了二等奖!</c:when>
    <c:when test="${luck==9}">恭喜你中了三等奖!</c:when>
    <c:otherwise>谢谢参与,欢迎再来!</c:otherwise>
</c:choose>

<hr>
forEach标签用法示例(循环结构)<br/>
<%
    List<String> users = new ArrayList<String>();
    users.add("admin");
    users.add("howard");
    users.add("smith");
    users.add("green");
    request.setAttribute("users", users);
%>

<c:forEach items="${users}" var="user">
    <c:out value="${user}"/><br/>
</c:forEach>
</body>
</html>

启动服务器,访问http://localhost:8080/JSTLELDemo/demo03.jsp:
在这里插入图片描述
在web目录里创建演示页面demo04.jsp
在这里插入图片描述

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>formateDate标签应用示例</title>
</head>
<body>
<h3>formateDate标签应用示例</h3>
<jsp:useBean id="now" class="java.util.Date"/>
<fmt:formatDate var="date" value="${now}"
                type="date" dateStyle="default"/>
<fmt:formatDate var="time" value="${now}"
                type="time" timeStyle="default"/>
<table border="1">
    <tr>
        <td>序号</td>
        <td>样式</td>
        <td>日期</td>
        <td>时间</td>
    </tr>
    <tr>
        <td>1</td>
        <td>default</td>
        <td>${date}</td>
        <td> ${time}</td>
    </tr>

    <fmt:formatDate var="date" value="${now}"
                    type="date" dateStyle="short"/>
    <fmt:formatDate var="time" value="${now}"
                    type="time" timeStyle="short"/>
    <tr>
        <td>2</td>
        <td>short</td>
        <td>${date}</td>
        <td> ${time}</td>
    </tr>

    <fmt:formatDate var="date" value="${now}"
                    type="date" dateStyle="medium"/>
    <fmt:formatDate var="time" value="${now}"
                    type="time" timeStyle="medium"/>
    <tr>
        <td>3</td>
        <td>medium</td>
        <td>${date}</td>
        <td> ${time}</td>
    </tr>

    <fmt:formatDate var="date" value="${now}"
                    type="date" dateStyle="long"/>
    <fmt:formatDate var="time" value="${now}"
                    type="time" timeStyle="long"/>
    <tr>
        <td>4</td>
        <td>long</td>
        <td>${date}</td>
        <td> ${time}</td>
    </tr>

    <fmt:formatDate var="date" value="${now}"
                    type="date" dateStyle="full"/>
    <fmt:formatDate var="time" value="${now}"
                    type="time" timeStyle="full"/>
    <tr>
        <td>5</td>
        <td>full</td>
        <td>${date}</td>
        <td> ${time}</td>
    </tr>
</table>
<p/>
<fmt:formatDate value="${now}" var="result"
                type="both" pattern="yyyy年MM月dd日 hh时mm分ss秒"/>
自定义显示当前时间:${result}
</body>
</html>

启动服务器,访问http://localhost:8080/JSTLELDemo/demo04.jsp:
在这里插入图片描述

CKEditor在线编辑器

一、CKEditor概述

1、在页面头部引入ckeditor核心文件ckeditor.js

<script type="text/javascript" src="ckeditor/ckeditor.js"></script>

2、在使用编辑器的地方插入文本区控件

<textarea id="mckeditor" cols="20" rows="2" class="ckeditor"></textarea>

注意在控件中加上 class=“ckeditor” 。

3、将相应的控件替换成编辑器代码

<script type="text/javascript">
 
    CKEDITOR.replace('mckeditor');
 
</script>

4、配置ckeditor编辑器

ckeditor的配置都集中在 ckeditor/config.js 文件中,下面是一些常用的配置参数:

CKEDITOR.editorConfig = function( config )
 
{
 
    config.language = 'zh-cn'; // 配置语言   
 
    config.uiColor = '#FFF'; // 背景颜色   
 
    config.width = 'auto'; // 宽度   
 
    config.height = '300px'; // 高度   
 
    config.skin = 'office2003'; // 界面v2,kama,office2003   
 
    config.toolbar = 'Full'; // 工具栏风格Full,Basic 
 
    config.font_names='宋体/宋体;黑体/黑体;仿宋/仿宋_GB2312;楷体/楷体_GB2312;隶书/隶书;幼圆/幼圆;'+ config.font_names; // 将中文字体加入到字体列表    
 
};

AJAX基础

一、AJAX概述

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

在创建一个XMLHttpRequest的对象之前,必须首先确定用户当前使用的浏览器类型,之后根据浏览器类型创建合适的XMLHttpRequest对象,如果为普通的FireFox,则直接使用new XMLHttpRequest()的方式创建;而如果IE浏览器,则通过new ActiveXObject()的方式进行创建。

XMLHttpRequest对象的属性
在这里插入图片描述
readyState一共有5种取值:

    0:请求没有发出(在调用open()函数之前)
    1:请求已经建立但还没有发出(在调用send()函数之前)
    2:请求已经发出正在处理之中(这里通常可以从响应得到内容头部)
    3:请求已经处理,正在接收服务器的信息,响应中通常有部分数据可用,但是服务器还没有完成响应。
    4:响应已完成,可以访问服务器响应并使用它。

XMLHttpRequest对象的方法

在这里插入图片描述
XMLHttpRequest对象的open()和send()方法在回调函数中出现较多,一般都会用open()方法设置一个提交的路径,并通过地址重写的方式设置一些请求的参数,而真正的发出请求操作可以通过send()方法完成。异步验证时要执行用JavaScript操作。在XMLHttpRequest对象中可以使用responseXML()方法接收一组返回的XML数据,这些返回的XML数据可以动态生成(利用JDOM工具将数据库中的数据变为XML文件),也可以直接读取一个XML文件,当客户端接收读取的XML文件之后,可以通过DOM解析的方式对数据进行操作。

二、创建Web项目AjaxDemo

在这里插入图片描述
修改Web项目首页文件index.jsp
在这里插入图片描述
在web目录创建子目录data,在里面创建userlist.txt文件
在这里插入图片描述
在web目录创建getUserList.html页面
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取用户列表</title>
    <script>
        function loadUserList() {
            var xmlhttp;
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
                xmlhttp = new XMLHttpRequest();
            } else {
                // IE6, IE5 浏览器执行代码
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            // 新建一个HTTP请求,采用GET方式,请求采用异步方式
            //xmlhttp.open("GET", "/AjaxDemo/data/userlist.txt", true);
            // 新建一个HTTP请求,采用GET方式,请求采用同步方式
            xmlhttp.open("GET", "/AjaxDemo/data/userlist.txt", false);
            // 发送HTTP请求(POST方式请求可以传递参数)
            xmlhttp.send();

            // 监听请求状态变化,一旦有变化,执行相应的回调函数
            xmlhttp.onreadystatechange = function () {
                // 判断请求是否成功,响应是否完成
                if (xmlhttp.status == 200 && xmlhttp.readyState == 4) {
                    // 利用响应文本修改页面元素内容
                    document.getElementById("users").innerHTML = xmlhttp.responseText;
                }
            }
        }
    </script>
</head>
<body>
    <h3>用户列表</h3>
    <div id="users"></div>
    <hr />
    <button type="button" onclick="loadUserList()">获取用户列表</button>
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在这里插入图片描述
在web目录里创建login.html页面
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script>
        function login() {
            // 获取用户名与密码
            var username = document.getElementById("username").value;
            var password = document.getElementById("password").value;

            // 声明请求对象
            var xmlhttp;
            // 实例化请求对象
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari浏览器里执行代码
                xmlhttp = new XMLHttpRequest();
            } else {
                // IE5, IE6 浏览器里执行代码
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            // 监听请求状态变化,一旦有变化,执行相应的回调函数
            xmlhttp.onreadystatechange = function () {
                // 判断请求是否成功,响应是否完成
                if (xmlhttp.status == 200 && xmlhttp.readyState == 4) {
                    // 根据返回值不同跳转不同的页面
                    if (xmlhttp.responseText == "success") {
                        // 跳转到登录成功页面,传递用户名
                        window.location = "success.html?username=" + username;
                    } else {
                        // 跳转到登录失败页面,传递用户名
                        window.location = "failure.html?username=" + username;
                    }
                }
            }

            // 新建HTTP请求,采用POST方式,请求采用异步方式
            xmlhttp.open("POST", "/AjaxDemo/login", true);
            // 设置请求头
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            // 定义要传递的数据
            var data = "username=" + encodeURIComponent(username) + "&password=" + encodeURIComponent(password);
            // 发送请求,传递数据
            xmlhttp.send(data);
        }

        function reset() {
            // 清空用户名与密码数据
            document.getElementById("username").value = "";
            document.getElementById("password").value = "";
        }
    </script>
</head>
<body>
<h3 style="text-align: center">用户登录</h3>
<table border="1" cellpadding="10" style="margin: 0px auto">
    <tr>
        <td align="center">用户名</td>
        <td><input type="text" id="username"></td>
    </tr>
    <tr>
        <td align="center">密&nbsp;&nbsp;码</td>
        <td><input type="password" id="password"></td>
    </tr>
    <tr align="center">
        <td colspan="2">
            <button type="button" οnclick="login()">登录</button>
            <button type="button" οnclick="reset()">重置</button>
        </td>
    </tr>
</table>
</body>
</html>

启动服务器,查看运行效果:
在这里插入图片描述
在src里创建net.hw.servlet包,在里面创建LoginServlet
在这里插入图片描述

package net.xsp.servlet;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:登录处理程度
 * 作者:向仕平
 * 日期:2019年11月19日
 */
@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置请求对象字符编码
        request.setCharacterEncoding("utf-8");
        // 获取登录表单提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 判断是否登录成功,返回不同的数据
        PrintWriter out = response.getWriter();
        if (username.equals("root") && password.equals("123456")) {
            out.print("success");
        } else {
            out.print("failure");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

创建登录成功页面success.html
在这里插入图片描述
创建登录失败页面failure.html
在这里插入图片描述
启动服务器,查看运行效果
在这里插入图片描述
在web目录里创建getJSONData.html页面
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>从后台获取JSON数据</title>
    <script>
        function getJsonData() {
            // 声明请求对象
            var xmlhttp;
            // 实例化请求对象
            if (window.XMLHttpRequest) {
                // IE7+, Firefox, Chrome, Opera, Safari浏览器里执行代码
                xmlhttp = new XMLHttpRequest();
            } else {
                // IE5, IE6 浏览器里执行代码
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            // 监听请求状态变化,一旦有变化,执行相应的回调函数
            xmlhttp.onreadystatechange = function () {
                // 判断请求是否成功,响应是否完成
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    // 利用响应文本设置页面元素内容
                    document.getElementById("json_data").innerText = xmlhttp.responseText;
                    // 让【解析JSON数据】按钮可见
                    document.getElementById("btnParse").hidden = false;
                }
            }

            // 新建一个HTTP请求,采用GET方式,请求采用异步方式
            xmlhttp.open("GET", "/AjaxDemo/getJson", true);
            // 发送HTTP请求,不传递数据
            xmlhttp.send();
        }
    </script>
</head>
<body>
<h3>从后台获取JSON数据</h3>
<button type="button" onclick="getJsonData()">获取JSON数据</button>
<div id="json_data"></div>
<button id="btnParse" type="button" onclick="parseJsonData()" hidden="hidden">解析JSON数据</button>
<div id="parse_json_data"></div>
<script>
    // 解析JSON数据函数
    function parseJsonData() {
        var strJson = document.getElementById("json_data").innerText;
        var objJson = JSON.parse(strJson);
        var data = "";
        for (key in objJson) {
            data = data + key + ": " + objJson[key] + "<br/>";
        }
        document.getElementById("parse_json_data").innerHTML = data;
    }
</script>
</body>
</html>

在net.hw.servlet包里创建GetJsonServlet类
在这里插入图片描述

package net.xsp.servlet;

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.IOException;
import java.io.PrintWriter;

/**
 * 功能:获取JSON数据控制程序
 * 作者:向仕平
 * 日期:2019年11月28日
 */

@WebServlet(name = "GetJsonServlet", value = "/getJson")
public class GetJsonServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 定义打印输出流对象
        PrintWriter out = response.getWriter();
        // 定义JSON字符串
        String strJson = "{\"username\": \"howard\", \"password\": \"903213\"}";
        // 向客户端返回JSON字符串
        out.write(strJson);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }
}

在web目录创建js子目录,添加jQuery脚本库文件
在这里插入图片描述
在web目录创建获取json数据页面getJsonData02.html
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>获取JSON数据</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script>
        // (function init() {  不用调用函数就会执行
        //     alert("测试")
        // })();

        $(function () {
            // 获取JSON数据按钮单击事件处理
            $('#btnGetJson').click(function () {
                $.ajax({
                    url: "/AjaxDemo/getJson",
                    type: "get",
                    datatype: "json",
                    success: function (data) {  // 请求完成
                        $('#json_data').html(data);
                        $('#btnParse').css({"display": "inline"});
                    }
                });
            });

            // 解析JSON数据按钮单击事件处理
            $('#btnParse').click(function () {
                var strJson = $('#json_data').text();
                var objJson = JSON.parse(strJson);
                var data = "";
                for (var key in objJson) {
                    data = data + key + ": " + objJson[key] + "<br/>";
                }
                $('#parse_json_data').html(data);
            });
        });
    </script>
</head>
<body>
    <h3>从后台获取JSON数据</h3>
    <button id="btnGetJson" type="button">获取JSON数据</button>
    <div id="json_data"></div>
    <button id="btnParse" type="button" hidden="hidden">解析JSON数据</button>
    <div id="parse_json_data"></div>
</body>
</html>

启动服务器,查看运行效果
在这里插入图片描述
在web目录里创建登录页面login02.html
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户登录</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script>
        $(function () {
            $("login").click(function () {
                // 获取用户名与密码数据
                var username = $('#username').val();
                var password = $('#password').val();
                // 提交ajax请求
                $.ajax({
                    type: "post",
                    url: "/AjaxDemo/login",
                    data:
                        {
                            "username": username,
                            "password": password
                        },
                    datatype: "json",
                    success: function (data) {
                        if (data == "success") {
                            $(location).attr('href', 'success.html?username=' + username);
                        } else {
                            $(location).attr('href', 'failure.html?username=' + username);
                        }
                    }
                });
            });

            $('#reset').click(function () {
                // 清空用户名与密码框
                $('#username').val('');
                $('#password').val('');
            });
        });
    </script>
</head>
<body>
    <h3 style="text-align: center">用户登录</h3>
    <table border="1" cellpadding="10" style="margin: 0px auto">
        <tr>
            <td align="center">用户名</td>
            <td><input type="text" id="username" name="username"/></td>
        </tr>
        <tr>
            <td align="center">密&nbsp;码</td>
            <td><input type="password" id="password" name="password"/></td>
        </tr>
        <tr align="center">
            <td colspan="2">
                <button id="login" type="button">登录</button>
                <button id="reset" type="button">重置</button>
            </td>
        </tr>
    </table>
</body>
</html>

学习总结

Jsp简单说明

Jsp和Servlet的本质是一样的。Jsp页面由两部分组成:
静态部分:标准的HTMl标签,静态的页面内容,与HTML页面相同
动态部分:受Java代码控制的内容,这些内容由java脚本动态生成

Jsp注释:
<%-- 注释内容 --%>

HTML注释:
<!-- 注释内容 -->

Jsp声明:
<%! 声明部分 %>

Jsp输出表达式:
<%= 表达式 %>

Jsp的3个编译指令

page:该指令是针对当前页面的指令
include:用于指定包含另一个页面
taglib:用于定义和访问自定义标签

语法:<%@ 编译指令名 属性名=“属性值” %>

page指令:

language:声明脚本语言类型,一般是java,只能是java
extends:指定jsp页面编译之后所产生的java类所继承的父类或者接口
import:用来导入包
session:jsp页面是否需要HttpSession
buffer:指定jsp页面的缓冲区的大小,默认值为8kb
autoFlush:缓冲区溢出时,是否强制输出缓冲区的内容
info:设置该jsp程序的信息
errorPage:指定错误处理界面
isErrorPage:设置本jsp程序是否为错误处理程序
pageEncoding:设置生成网页的字符集编码

include指令:
把一个外部文件嵌入当前的jsp页面中,同时解析这个页面的Jsp语句,这是静态include语句,他会把目标页面的其他编译指令也包含进来如果两个页面的编译指令冲突,页面就会出错,但是动态的include则不会。

语法<%@ include file=“文件路径/文件名”%>

Jsp的7个动作指令

编译指令是通知Servlet引擎处理消息
动作指令知识运行时的动作

jsp:forward:执行页面转向,将请求的处理转发到下一个页面
jsp:param:传递参数,必须和其他支持参数的标签一起使用
jsp:include:动态的引入一个jsp页面
jsp:plugin:下载javaBean和Applet到客户端执行
jsp:useBean:创建一个useBean的实例
jsp:setProperty:设置javaBean实例的属性值
jsp:getProperty:输出javaBean实例的属性值

forward指令:
将页面的请求转发到一个新的页面,可以是静态的HTML页面,也可以是动态的jsp页面,或者转发到容器中的Servlet

语法:
对于jsp1.0:
<jsp:forward page=“URL”>
对于jsp1.1:(用于转发时增加额外的请求参数)
<jsp: forward page=“URL”>
<jsp:param…/>
</jsp:forward>

include指令:
他是一种动态的include指令,用于包含某个页面,他不会导入被include页面的编译指令,只导入页面的body内容插入本页面。
语法:
<jsp:include page=“URL” flush=“true|false”>
<jsp:param…/>
</jsp:include>

其中flush属性:指定输出缓存是否转移到被导入的文件中,如果为true,则包含在被导入的文件中,如果为false,则包含在原文件中。

静态导入和动态导入的三个区别:
1、静态导入是将被导入页面的代码完全融合,两个页面融合成一个整体的Servlet;动态导入则在Servlet中使用include方法来引入被导入的页面的容。
2、静态导入时,被导入的页面的编译指令会产生作用;动态导入时被导入的编译指令则会失去作用,只是插入被导入页面的body内容
3、动态导入还可以增加额外的参数

forward动作指令和include动作指令的区别:
执行forward时,被forward的页面将完全代替原有页面,执行include时,被include的页面知识插入原有的页面。
forward拿目标页面代替原有页面,include则拿目标页面插入原有的页面。

useBean指令:

<jsp:useBean id=“name” class="classname"scope=“page|request|session|application”/>

id属性就是Javabean的实例名,class属性确定了JavaBean的实现类
scope属性指定javaBean市里的作用范围:
page:该javaBean实例只在该页面有效
request:在本次请求内有效
session:在本次session内有效
application:在本应用内一直有效

setProperty指令:

<jsp:setProperty name=“BeanName” property=“propertyName” value=“value”/>

name属性确定了javaBean的实例名;property属性确定需要设置的属性名;value属性则确定需要设置的属性值

getPeoperty指令:

<jsp:getProperty name=“BeanName” property=“propertyName”/>

name属性确定了需要输出的javaBean的实例名;property属性确定需要输出的属性名。

param指令:

用于设置参数值,本身不能单独使用,没有什么意义, 一般都结合下面的三个指令使用:

1、jsp:include
param指令把参数传入被导入的页面
2、jsp:forward
param指令把参数传向被转入的页面
3、jsp:plugin
param指令把参数传入页面中的javabean或者Applet

转眼间一学期就快过去了,在学校的这几个月来,关于JavaWeb的学习过程中,自己从中得到的收获依旧是巨大的,加之最后的西蒙购物网项目开发,使得自己在这方面进一步提高。综合一学期的学习我给自己打分90分。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值