Javaweb143-155:JavaWeb(七)

开始时间:2021-07-27

EL工具包

传统方式进行JSP开发

package controller;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class OneServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext application = req.getServletContext();
        HttpSession session = req.getSession();
        //三种方式添加到作用域对象
        application.setAttribute("SID", 001);
        session.setAttribute("SName", "Xiaowang");
        req.setAttribute("SHome", "Beijing");
        
        //请求转发
        req.getRequestDispatcher("/index_1.jsp").forward(req, resp);
    }
}

<%--
  Created by IntelliJ IDEA.
  User: Chenzhijin
  Date: 2021/7/28
  Time: 9:24
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    //对应方式对应取数据
    Integer SID = (Integer) application.getAttribute("SID");
    String SName = (String) session.getAttribute("SName");
    String SHome = (String) request.getAttribute("SHome");
%>
学员ID:<%=SID%><br/>
学员Name:<%=SName%><br/>
学员Home:<%=SHome%><br/>

用EL表达式来展示
大大提高效率

<hr/>
学员ID:${applicationScope.SID}<br/>
学员Name:${sessionScope.SName}<br/>
学员Home:${requestScope.SHome}<br/>

在这里插入图片描述
还可以进一步简化,省略作用域对象的别名

学员ID:${applicationScope.SID}<br/>
学员Name:${sessionScope.SName}<br/>
学员Home:${requestScope.SHome}<br/>
学员Home:${SHome}<br/>

一样能实现输出

但如果有对象不同,但属性名相同的情况

首先定位【pageContext】,再看【request】,然后【session】,最后看【application】

  • 容易降低程序执行速度【南辕北辙】
  • 容易导致数据定位错误

设计目的,就是简化从pagecontext读取共享数据并输出难度

再看一个例子

        req.setAttribute("SHome", "Beijing");
        req.setAttribute("key1", "100");
        req.setAttribute("key2", 200);

传统方式和EL表达式

<%

    String num1 = (String) request.getAttribute("key1");
    Integer num2 = (Integer) request.getAttribute("key2");
    int sum = Integer.valueOf(num1)+num2 ;
%>

求和结果sum等于:<%=sum%><br/>

EL表达式结果:${key1+key2}

在这里插入图片描述

可以用来处理关系表达式

<!--传统Java命令方式实现关系运算输出-->
<%
    String age = (String) request.getAttribute("age");
    if
    (
            Integer.valueOf(age) >= 18) {
%>
欢迎光临<br/>
<%
} else {
%>
谢绝入内<br/>
<%
    }
%>

EL表达式

${age>=18?"欢迎":"谢绝入内"}

读取请求包内容

键入http://localhost:8080/01_JSP_war_exploded/index_1.jsp?userName=555&password=123

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

来访者姓名:${param.userName}<br/>
来访者密码:${param.password}

若请求参数是[一个请求参数关联多个值]此时可以通过paramValues读取请求参数下指定位置的值并写入到响应体

http://localhost:8080/01_JSP_war_exploded/index_2.jsp?pageNo=1&pageNo=2&pageNo=3

pageNo1:${paramValues.pageNo[0]}<br/>
pageNo2:${paramValues.pageNo[1]}<br/>
pageNo3:${paramValues.pageNo[2]}

得到结果

pageNo1:1
 pageNo2:2
 pageNo3:3 

我们再看一个例子
在question_update.jsp中

<form action="/TestSystem/QuestionUpdate" method="get">

                <table border="2">
                    <tr>
                        <td>题目编号:</td>
                        <td><input type="text" name="questionId" value="<%=q.getQuestionId()%>" readOnly></td>
                    </tr>
                    <tr>
                        <td>题目:</td>
                        <td><input type="text" name="title" value="<%=q.getTitle()%>"></td>
                    </tr>
                    <tr>
                        <td>A:</td>
                        <td><input type="text" name="optionA" value="<%=q.getOptionA()%>"></td>
                    </tr>
                    <tr>
                        <td>B:</td>
                        <td><input type="text" name="optionB" value="<%=q.getOptionB()%>"></td>
                    </tr>
                    <tr>
                        <td>C:</td>
                        <td><input type="text" name="optionC" value="<%=q.getOptionC()%>"></td>
                    </tr>
                    <tr>
                        <td>D:</td>
                        <td><input type="text" name="optionD" value="<%=q.getOptionD()%>"></td>
                    </tr>
                    <tr>
                        <td>正确答案:</td>
                        <td>
                            <input type="radio" name="answer" value="A" <%="A".equals(q.getAnswer())?"checked":""%> >A
                            <input type="radio" name="answer" value="B" <%="B".equals(q.getAnswer())?"checked":""%> >B
                            <input type="radio" name="answer" value="C" <%="C".equals(q.getAnswer())?"checked":""%> >C
                            <input type="radio" name="answer" value="D" <%="D".equals(q.getAnswer())?"checked":""%> >D
                        </td>
                    </tr>
                    <tr>
                        <td><input type="submit" value="更新试题"/></td>
                        <td><input type="reset" ></td>
                    </tr>
                </table>
            </form>

这种代码也要改为EL表达式
原:

<td><input type="text" name="questionId" value="<%=q.getQuestionId()%>" readOnly></td>

改:

<td><input type="text" name="questionId" value="${requestScope.key.questionId}" readOnly></td>

key后面跟的东西就是前面 name 里的东西

原:

<input type="radio" name="answer" value="A" <%="A".equals(q.getAnswer())?"checked":""%> >A

<input type="radio" name="answer" value="A" ${"A" eq key.answer?"checked":""} >A

自动出题功能

在MyLeft.HTML中要添加出题选项

   <li>考试管理</li>
    <ol>
        <li><a href="/TestSystem/QuestionRand" target="right">参加考试</a></li>
        <li><a href="/TestSystem/QuestionFind" target="right">试题信息查询</a></li>
    </ol>

在题库里随机选择4道题
那么得先构思SQL怎么写

select rand()#随机返回0-1之间的数
select * from question order by rand() limit 0,4 
# 此时rand返回的是0-9之间的数 0.6这种值会变为6 
# 如果整个序列只有8个字段,那么取9会再取余,用字段1来排序

需要写一个Random的Servlet

package Controller;

@WebServlet(name = "QuestionRandServlet", value = "/QuestionRandServlet")
public class QuestionRandServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.调用DAO对象随机从question表拿出4道题目
        QuestionDao dao = new QuestionDao();
        List questionList = null;
        questionList = dao.findRand();
        //2.将4道题目添加到request作为共享数据
        request.setAttribute("key", questionList);
        //3.请求转发,申请调用exam.jsp将4道题目写入到响应体
        request.getRequestDispatcher("/exam.jsp").forward(request, response);
    }

}

DAO里面补充方法findRand
基本就是照抄findAll里面的内容,只是sql语句变了一下

public List findRand() {
        String sql = "select * from question order by rand() limit 0,4";
        PreparedStatement ps = util.createPs(sql);
        ResultSet rs = null;
        List list = new ArrayList();
        try {
            rs = ps.executeQuery();
            while (rs.next()) {
                Integer quesitonId = rs.getInt("questionId");
                String title = rs.getString("title");
                String optionA = rs.getString("optionA");
                String optionB = rs.getString("optionB");
                String optionC = rs.getString("optionC");
                String optionD = rs.getString("optionD");
                String answer = rs.getString("answer");
                Question question = new Question(quesitonId, title, optionA, optionB, optionC, optionD, answer);
                list.add(question);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            util.close(rs);
        }
        return list;
    }

转发给exam.jsp
所以得补充一个exam.jsp

<%@ page import="Entity.Question" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<center>
    <form action="/TestSystem/exam">
        <table border="2">
            <tr>
                <td>试题编号</td>
                <td>题目信息</td>
                <td>A</td>
                <td>B</td>
                <td>C</td>
                <td>D</td>
                <td>答案</td>
            </tr>

            <%
                List<Question> questionList =(List) session.getAttribute("key");
                for(Question question:questionList){
            %>
            <tr>
                <td><%=question.getQuestionId()%></td>
                <td><%=question.getTitle()%></td>
                <td><%=question.getOptionA()%></td>
                <td><%=question.getOptionB()%></td>
                <td><%=question.getOptionC()%></td>
                <td><%=question.getOptionD()%></td>
                <td>
                    <input type="radio" name="answer_<%=question.getQuestionId()%>" value="A"/>A
                    <input type="radio" name="answer_<%=question.getQuestionId()%>" value="B"/>B
                    <input type="radio" name="answer_<%=question.getQuestionId()%>" value="C"/>C
                    <input type="radio" name="answer_<%=question.getQuestionId()%>" value="D"/>D
                </td>
            </tr>
            <%
                }
            %>
            <tr align="center">
                <td colspan="3"><input type="submit" value="交卷"></td>
                <td colspan="4"><input type="reset" value="重做"></td>
            </tr>
        </table>
    </form>

</center>
</body>
</html>

因为EL不能用来遍历集合,所以还是有部分写的传统的JSP形式

 <td>
                    <input type="radio" name="answer_<%=question.getQuestionId()%>" value="A"/>A
                   

这里的name不能直接写answer,不然四道题16个选项只能选择一个,所以要给4道题分别命名

在线阅卷

阅卷需要将用户提交的答案和设置的答案进行比较,那么需要用session进行数据共享,才能进行验证。

所以就要修改
QuestionRandServlet

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.调用DAO对象随机从question表拿出4道题目
        QuestionDao dao = new QuestionDao();
        List questionList = null;
        //用false防止恶意登录
        HttpSession session = request.getSession(false);
        questionList = dao.findRand();
        //2.将4道题目添加到request作为共享数据
        session.setAttribute("key", questionList);
        //3.请求转发,申请调用exam.jsp将4道题目写入到响应体
        request.getRequestDispatcher("/exam.jsp").forward(request, response);
    }

同时修改exam.jsp
获取方式改为

List<Question> questionList =(List) session.getAttribute("key");

写一个ExamServlet用于处理结果

package Controller;

import Entity.Question;

public class ExamServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false);
        List<Question> questionList = null;
        int score = 0;
        //1.从当前用户私人储物柜得到系统提供四道题目信息
        questionList = (List) session.getAttribute("key");
        //2.从请求包读取用户对于4道题目给出答案
        for (Question question : questionList) {
            String answer = question.getAnswer();
            Integer questionId = question.getQuestionId();
            //这里answer_ +questionId  是为了和上传给网页的格式一致
            String userAnswer = request.getParameter("answer_" + questionId);
            //3.判分
            if (userAnswer.equals(answer)) {
                score += 25;
            }
        }

        //4.将分数写入到request中,作为共享数据
        request.setAttribute("info", "本次考试成绩: " + score);
        //5.请求转发调用jsp将用户本次考试分数写入到响应体
        request.getRequestDispatcher("info.jsp").forward(request, response);
    }
}




网络通信框图

在这里插入图片描述

模拟面试

谈谈本次做的在线考试管理系统

功能:

  • 用户信息注册、查询
  • 试题信息注册、查询
  • 考试出题、阅卷

技术:
Servlet、JDBC、MySQL、EL表达式

缺陷:
数据库路径写死了,没有使用反射来配置等

项目介绍

一。项目总体介绍:

  1. 介绍项目客户:
  2. 介绍项目主要功能
  3. 介绍项目使用技术
  4. 介绍项目使用服务器

  举栗子:

        我之前参与 吉林大学在线考试管理系统开发。这个项目主要负责吉大在线考试与在线阅卷功能。
    这个系统使用Servlet ,jsp,jdbc,javascript(从服务端向浏览器过渡)
    这个系统使用Http服务器是tomcat,使用数据库服务器mysql

二。项目功能介绍:捡主要功能

        这个系统大体由【学员信息管理】,【试题信息管理】,【在线考试管理】三个模块组成

三。项目特色介绍:

         1.使用监听器模拟了数据库连接池功能,节省Connection创建与销毁时间,提高执行速度
       增加QPS(服务器在单位时间接收访问量)

         2.使用过滤器防止用户恶意登录行为,增加项目安全性

四。介绍自己在项目参与某一个功能:

      参与功能【学员信息注册】
     首先根据互联网通信特征,画出来流程图
     根据流程图分析开发功能,然后进行开发与测试

什么时候用post 什么时候用get

参考前面的博客

请求方式携带请求参数浏览器地址栏请求参数信息保存在服务器返回的资源文件
get不能超过4K必须展示请求参数信息Http请求协议包【请求头】保存在浏览器缓存
post任意数量必须隐藏请求参数信息Http请求协议包中【请求体】禁止浏览器保存

考虑到POST请求方式,用户可以将【病毒文件内容】发送到服务器上进行攻击。因此绝大多数门户级网站拒绝接收POST请求,日常开发过程绝大多数请求都是GET(不涉及实时变化)
但是注意到坑,get携带参数不能超过4K,但是返回的文件有多大和这个4K没有关系,可以用Get得到大文件的
在某些特殊场景下必须使用POST

  • 文件上传,必须使用POST
  • 发起登录验证请求,必须使用POST
  • 索要服务器中实时变化数据时(股票价格,车票数量。。。),必须采用POST

服务器读取到中文乱码

推测浏览器请求方式为Post
参考博客

浏览器以GET方式发送请求,请求参数保存在==【请求头】,在Http请求协议包到达Http服务器之后,第一件事就是进行解码请求头二进制内容由Tomcat负责解码,Tomcat默认使用【utf-8】字符集,可以解释一切国家文字
浏览器以POST方式发送请求,请求参数保存在【请求体】==,在Http请求协议包到达Http服务器之后,第一件事就是进行解码请求体二进制内容由当前请求对象(request)负责解码。request默认使用[ISO-8859-1]字符集,一个东欧语系字符集此时如果请求体参数内容是中文,将无法解码只能得到乱码

在Post请求方式下,在读取请求体内容之前,应该通知请求对象使用utf-8字符集对请求体内容进行一次重新解码

请求方式请求参数保存在解码解码字符集
Get请求头由Tomcat负责解码【utf-8】
Post请求体由当前请求对象(request)负责解码【ISO-8859-1】

Servlet里面几种作用域对象

参考博客
作用域对象存在于服务端内存中,为Servlet提供数据共享对象,Cookie存在于浏览器中,虽然能提供共享,但不是作用域对象。

servletcontext接口【全局作用域】对象
Httpsession接口【会话作用域对象】
HttpservletRequest接口【请求作用域对象】

cookie和Session区别

参考博客

名称CookieHttpSession
存储位置存放在客户端计算机(浏览器内存/硬盘)存放在服务端计算机内存
数据类型存储共享数据类型只能是String可以存储任意类型的共享数据object
数据数量一个cookie对象只能存储一个共享数据使用map集合存储共享数据,可以存储任意数量共享数据
参照物相当于客户在服务端【会员卡】Httpsession相当于客户在服务端【私人保险柜】

请求转发和重定向的区别

参考博客

调用规则浏览器发送请求数请求方式响应包返回地址栏
请求转发1次所有的请求方式和浏览器发过来的保持一致,浏览器用post/get那么Servlet这边也是对应的
重定向至少2次get状态码302地址栏会变化

多线程工作状态

参考博客
在这里插入图片描述

Sql语句执行优先级

优先级语句
1from
2where
3group by
4having
5select
6order by

count(*)和count(字段)

前者统计临时表总行数为多少
后者统计该字段下内容不为null 的 行数

Java扩容因子

参考博客
HashMap默认初始化容量为16,初始化容量必须是2的倍数,可以提高存取效率。默认加载因子为0.75
意思是当容量用掉75%时,数组开始扩容

在JDK8之后,如果Hash表,单向链表的元素>=8,那么该单向链表会变成红黑树,当红黑树上的节点<6时,红黑树会变回单向链表。为了提高效率,二叉树检索会再次缩小检索范围,初始化容量16,默认加载因子0.75,扩容后容量为原容量2倍

容器容量存储类型
数组一定一种
List有扩容因子,可增可以多种

继承

一个类的构造方法是私有的话,是不可以有子类的
因为创建子类,JVM会先创建一个父类对象,构造方法私有,new不出来

JDBC六步

参考博客

JDBC编程六步

  • 第一步:注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库)
  • 第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭
  • 第三步:获取数据库操作对象(专门执行sql语句的对象)
  • 第四步:执行SQL语句(DQLDML. …)
  • 第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。)
  • 第六步:释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)

数据库中char和varchar的区别

前者定长不可变,后者定长可变
存储字符串都有空格结尾,存在varchar里面比较好
char自动补齐功能,放三个字符只给了两个,那么最后一个会补齐空格,提取的时候会砍掉结尾空格

结束时间:2021-08-30

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值