JavaWeb 07 JSP

JSP

Java服务器页面,Java Server Pages,动态网页开发技术

页面可包含:指令,脚本(java代码)脚本表达式(输出),声明,HTML,CSS,JSP

JSP实现原理
Tomcat会将xxx.isp转换成Java代码,这个类会继承HttpServlet,进而编译成.class文件运行,最终将运行结果通过response响应给客户端(这个响应会动态使用out.write 拼出一个网页)。

jsp实际上是一个Servlet,响应回游览器的页面中只有HTML的内容了,是被jsp的Servlet write写回来的

脚本

脚本可以编写Java语句,变量,方法或表达式

<%--    脚本表达式 末尾不可有分号--%>
    <%=date%>
<%--声明:成员变量,方法--%>
    <%!
        private String email="aaa@qq.com";
        public String  getEmail(){
            return email;
        }
    %>
    <br>
    <%=email%><br>
    <%=getEmail()%>

在这里插入图片描述

JSP指令

在这里插入图片描述

page指令

一般都不会更改
属性之间加空格
在这里插入图片描述

include

被包含的文件不会被编译成class文件
相当于把被包含文件的内容全部copy过来到本文件中,仅仅如此,故要将被包含文件中的除输出语句外的部分删除,这部分指属于HTML文件的部分
在这里插入图片描述

动作标签

动作标签是JSP页面在运行期间的命令

被包含文件会被编译为class文件,将其输出结果引入到JSP文件中
在这里插入图片描述
在这里插入图片描述
生成的对象会被加入到pageContext中
在这里插入图片描述

<%--include 导入文件--%>
    <jsp:include page="header.jsp"></jsp:include>
<%--useBean 创建类对象--%>
<%--    <%--%>
<%--        User user = new User();--%>
<%--        pageContext.setAttribute("user",user);--%>
<%--        // 这两句话相当于下边的一句话--%>
<%--    %>--%>
<%--这个类必须写全限定名,且类必须在包中--%>
<%--这个对象会被放置到pageContext中--%>
    <jsp:useBean id="user" class="com.User"></jsp:useBean>
<%--设置属性--%>
    <jsp:setProperty name="user" property="name" value="chichi"></jsp:setProperty>
<%--获得属性 --%>
    <jsp:getProperty name="user" property="name"/>

在这里插入图片描述

<%--转发,设置编码,防止乱码,接受页面中早已设置好编码,仅有在中间这次转发时编码可能出现问题--%>
	<%
        request.setCharacterEncoding("utf-8");
    %>
<%--转发时传递数据
    1.地址后面加参数,添加参数
    2.使用jsp:param添加
--%>

    <jsp:forward page="login.jsp?username=chichi">
        <jsp:param name="username" value="chichi"/>
    </jsp:forward>

内置对象

九个
在这里插入图片描述
简记 RRSACEOPP

out

out输出内容会先输出到buffer缓冲区(8k)中,再输出到网页中

在这里插入图片描述

<% out.println("ccc"); %>

如果想要混用,要对out及时刷新,使用out.flush 方法,否则会出现后写的getWriter().write()会比先写的out.println先一步网页中输出。

pageContext

作用域相当于一个集合
pageContext虽然是最小的,但其功能是最强大的
在这里插入图片描述
在这里插入图片描述
功能:
1.作为域对象使用

1.1操作当前页面域
1.2操作其他三个作用域
其removeAttribute方法,若不指定具体的域,会把四个域中符合条件的全部删除

2.获取其他八个内置对象

    <%
        // 1.1 操作当前页面域
        pageContext.setAttribute("name","chichi");
        String name = (String) pageContext.getAttribute("name");
        out.println(name);
        // 1.2 操作其他三个域对象
        pageContext.setAttribute("requestDate","chichi", PageContext.REQUEST_SCOPE);
//          remove方法在不指定域的情况下会删除所有域中name参数相同的
        pageContext.removeAttribute("name");
//        按照PRSA的循序一次寻找,找到返回,找不到返回null
        pageContext.findAttribute("name");
//        功能2.获取其他八个内置对象
        ServletRequest request1 = pageContext.getRequest();
        HttpSession session1 = pageContext.getSession();
    %>

四大域对象

使用时能用小的就别用大的,从上到下,组件增大
在这里插入图片描述

EL表达式

主要用于获取作用域中的数据
在这里插入图片描述
没找到返回"" JSP脚本没找会返回null

    <%
        // 先放域中存放数据
        pageContext.setAttribute("username","chichi");
        pageContext.setAttribute("password","1234",PageContext.REQUEST_SCOPE);
        pageContext.setAttribute("address","上海",PageContext.SESSION_SCOPE);
    %>
<%--使用EL表达式获取--%>
    ${username}<br>
    ${password}<br>
    ${address}
<%--获取引用类型的属性--%>
    <%
        User user = new User("chichi",15,"上海");
        pageContext.setAttribute("user",user);
    %>
    ${user}
<%--    相当于调用get方法--%>
    ${user.name}
    ${user.address}
<%--若User还有一个其他类对象,如tel,tel中有个s属性--%>
    ${user.tel.s}
    
<%-- EL表达式获取List集合--%>
    <%
        ArrayList<String> list = new ArrayList<>();
        list.add("上海");
        list.add("北京");
        list.add("广州");
        list.add("深圳");
        pageContext.setAttribute("city",list);
    %>
    ${city}<br>
    ${city[0]}<br>
<%--    下标越界是返回一个""--%>
    ${city[10]}<br>
    ${city.get(0)}
<%--数组操作与集合相同 但没有get方法--%>

<%--获取map中数据--%>
    <%
        HashMap<String,String> map =new HashMap<>();
        map.put("chichi","yyds");
        map.put("666","000");
        pageContext.setAttribute("map",map);
    %>
    ${map}<br>
    ${map.chichi}
<%--    数字做键时仅能通过["666"]方式访问--%>
    ${map["666"]}

在这里插入图片描述
eq 等于 lt小于 gt大于 le小于等于 ge 大于等于

<%--    运算符= - * / %--%>
    ${10*5}
<%--大小判断--%>
<%--    字符串可使用== 实际使用equals 比的是指,不是地址--%>
    ${"abc"=="abc" }<br>
    ${100 lt 102}<br>
<%--逻辑运算--%>
    ${true&& false}<br>
    ${true || false}
    ${true and false}
    ${not true};
<%--三目运算符--%>
    ${gender=="1"?"男":"女"}
<%--判断空值--%>
<%--空字符串,null,空列表 empty判断均为空--%>
    <%        
        pageContext.setAttribute("address","");
        pageContext.setAttribute("user",null);
        pageContext.setAttribute("list",new ArrayList<String>());
    %>
<br>
    ${empty address}
    ${empty user}
    ${empty list}   

11个隐式对象

重要四个 pageScope requestScope sessionScope applicationScope,
最重要是pageContext

指定从那个域中取出对象
${requestScope.name}

Param指那些通过表单传入的参数,

在这里插入图片描述

<%-- 相当于 getAttritube--%>
    ${requestScope.name}
<%-- 相当于getParameter--%>
    ${param.name}

路径分类

在这里插入图片描述

<%-- 相当于 getAttritube--%>
    ${requestScope.name}
<%-- 相当于getParameter--%>
    ${param.name}

在这里插入图片描述

JSTL

是一个标签集合
可对EL获取到的数据进行逻辑操作,为EL完成数据的展示

导入jar包
在这里插入图片描述

导入core标签库
<%--导入标签库 c前缀代表后边的 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <h1>三个通用标签 set out remove</h1>
<%--    不指定域时 默认放到页面域--%>
    <c:set var="username" value="chichi" scope="page"></c:set>
    ${username}<br>
<%--  输出内容中有标签  out会编码后输出 直接使用EL表达式会标签写到网站上,被网页识别使用,不安全--%>
    <c:out value="使用out输出"></c:out><br>
    <c:out value="${username}"></c:out><br>
<%--    remove--%>
    <c:remove var="${username}"></c:remove>

if标签

在这里插入图片描述

<h1>if标签</h1>
    <c:if test="${10>5}">输出内容</c:if>

choose标签

在这里插入图片描述

<h1>choose标签</h1>
<c:choose>
    <c:when test="${15<5}">输出1</c:when>
    <c:when test="${10>5}">输出2</c:when>
</c:choose><br>

遍历forEach标签

在这里插入图片描述
varstatus属性值 current返回值 first,last是否开头结尾 index,count下标,分别从0,1开始

 <%
        ArrayList<String> list = new ArrayList<>();
        list.add("苹果");
        list.add("苹果");
        pageContext.setAttribute("list",list);
        HashMap<String, String> map = new HashMap<>();
        map.put("apple","苹果");
        map.put("ban", "香蕉");
        pageContext.setAttribute("map",map);
    %>
<%--    遍历list --%>
    <c:forEach var="d" items="${list}">
        ${d}
    </c:forEach>
<%--    遍历map--%>
    <c:forEach var="entry" items="${map}">
        ${entry.key}---${entry.value}
    </c:forEach><br>
<%--    下角标 vs.index从0开始 vs.count从一开始--%>
    <c:forEach var="d" items="${list}" varStatus="vs">
        ${vs.index}--${vs.count}
    </c:forEach><br>
<%-- 输出150 间隔1--%>
    <c:forEach var="num" begin="1" end="50" step="1">
        ${num}
    </c:forEach>

url标签

在这里插入图片描述
会自动带上下文路径,直接写文件名即可

<%--    url标签的使用:把连接进行格式化,自动重写url,自动编码--%>
    <c:url value="/servlet" var="myurl">
            <c:param name="param1" value="传参"></c:param>
        </c:url>
    <a href="${myurl}">去主页</a>

时间格式化

导入fmt标签库
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

时间格式化

    <%--时间格式化--%>
    <%
        Date date = new Date();
        pageContext.setAttribute("date",date);
    %>
    <fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>

MVC模式

在这里插入图片描述
优缺点
在这里插入图片描述

MVC 与三层架构

对应关系
Model :业务层Service ,数据访问层dao
View:JSP
Controller:Servlet 后两者 为三层架构中界面层
在这里插入图片描述
基于MVC的三层架构实现
在这里插入图片描述

区别
在这里插入图片描述

防止表单重复提交

在这里插入图片描述

令牌工具类

创建令牌与删除令牌方法

// 令牌生成器
public class TokenUtils {
//    生成随机令牌,放入session中
    public static void creatToken(HttpServletRequest request){
        try {
            request.setCharacterEncoding("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String token = System.currentTimeMillis()+""+new Random().nextInt(99999999);
        request.getSession().setAttribute("token",token);
    }
    // 令牌移除
    public static void removeToken(HttpServletRequest request){
        request.getSession().removeAttribute("token");
    }
}

转账页面

生成令牌,分别保存于服务器与客户端

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>转账页</title>
</head>
<body>
    <%
        // 生成令牌 并放入服务器Session中
        TokenUtils.creatToken(request);
    %>
    <form method="post" action="${pageContext.request.contextPath}/transservlet">
        <table>
            <tr>
                <th>对方卡号</th>
                <th><input type="text" name="toCard" > </th>
                // 客户端保存的令牌,表单提交时提交给服务器,用于比较
                <input type="hidden" name="token" value="${token}">
            </tr>
            <tr>
                <th>转账金额</th>
                <th><input type="text" name="money" > </th>
            </tr>

            <tr>
                <th><input type="submit" value="转账"></th>

            </tr>
        </table>
    </form>
</body>
</html>

令牌比较

重复判断方法,分别判断一下三种情况

1.通过地址栏传入的空令牌
2.通过地址栏传入的不一致令牌
3.正常情况,操作成功后删除了令牌,服务器无令牌,再次提交被判断为重复提交

操作成功后必须移除session中的令牌

    private static boolean isRepeat(HttpServletRequest request){
//        通过地址栏传入的空令牌 或者 传入的不一致令牌
        String token = request.getParameter("token");
        System.out.println(token);
        String serverToken = (String) request.getSession().getAttribute("token");
        System.out.println(serverToken);
        if (StringUtils.isEmpty(token)){
            System.out.println(1);
            return true;
        }
        if (!token.equals(serverToken)){
            System.out.println(2);

            return true;
        }
//        正常情况,不通过游览器输出框来传值,重复提交的情况仅有服务器中为空,而表单提交有值
//        操作过后移除Session中令牌,来禁止重复提交
        if (StringUtils.isEmpty(serverToken)) {
            System.out.println(3);

            return true;
        }
        return false;
    }

对两次操作时间间隔加入限制

//        对两次提交的时间间隔限制
        long currentTime = System.currentTimeMillis();
        Long lastTime = (Long) request.getSession().getAttribute("lastTime");
//        第一次操作时lastTime为空
        if (lastTime!=null){
            if ((currentTime-lastTime)<60000){
                request.setAttribute("message","提交间隔过短");
                request.getRequestDispatcher("/message.jsp").forward(request,response);
                return;
            }        }

操作成功后,在Session中放入放入上次操作的时间

request.getSession().setAttribute("lastTime",System.currentTimeMillis());

分页

在这里插入图片描述
在这里插入图片描述
0902web3
主要有五个核心的元素
当前页数
页面大小
总的页数
总的数据个数
一页的数据(可以用List存储)

请务必注意查询时使用的值并非当前页码,而是页数与页面大小的乘积,查询时使用中间变量保存

int temp = (pageNum-1)*pageSize;
List<Book> books = bookDao.queryList(temp, pageSize);
long l = bookDao.queryCount();
BookBean<Book> bookBean = new BookBean<>(pageNum,pageSize,l,books );
return bookBean;

优化界面元素,加入开始页码以及结束页码,从而展示页数

创建一个工具类,保存五个元素

//    总页数
    private int pageCount;
//    页码
    private int pageNum;
//    页大小
    private int pageSize;
//    总数据个数
    private long totalSize;
//    分页数据
    private List<T> data;
//    开始页以及末尾页 共五页,默认1-5页
    private int startPage = 1;
    private int endPage = 5;
    public BookBean( int pageNum, int pageSize, long totalSize, List<T> data) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.totalSize = totalSize;
        this.data = data;
        this.pageCount = (int) (totalSize%pageSize ==0?(totalSize/pageSize):(totalSize/pageSize+1));
        // 总页数小于页
        if (pageCount<5){
            endPage = pageCount;
        }
        // 末尾页限制
        if (pageNum>pageCount-4){
            startPage=pageCount-4;
            endPage=pageCount;
        }
        // 超过第四页时 页码开始变换
        if (pageNum>=4&&pageNum<pageCount){
            startPage = pageNum-2;
            endPage = pageNum+2;
        }
    }
    public BookBean() {
    }

切记,一定要判断字符串是否为null或者是空字符串,集合或者对象一定要判断是否为null或者长度是否大于零。

public class StringUtils {
    public static boolean isEmpty(String s){
//        为空时会返回true
        return s == null || s.trim().equals("");
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值