Bootstrap

javaweb-jsp的学习笔记+习题记录

javaweb

什么是javaweb?

    所有通过Java语言编写可以通过浏览器访问的程序的总称,叫JavaWeb。是基于请求和响应来开发的。

请求和响应

054c6e3d24cf4dfca67a291a2931fc2c.png

 web资源的分类

  • 静态资源:html、css、js、txt、mp4视频,jpg图片
  • 动态资源:jsp页面、Servlet程序

什么是C/S结构和B/S结构,各有什么优缺点

  •       C/S又称Client/Server或客户/服务器模式。服务器通常采用高性能的PC、工作站或小型机,并采用大型数据库系统。客户端需要安装专用的客户端软件。
  •      B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),服务器安装数据库。浏览器通过Web Server 同数据库进行数据交互。
  • 前端开发流程

  • a4d3a477a46c49dda27bf38897e73854.png网页的三大组成部分

  •      内容(结构),是我们在页面中可以看到的数据。我们称之为内容。一般内容我们使用html技术来展示。
  •      表现,指的是这些内容在页面上的展示形式。比如说。布局,颜色,大小等等。一般使用CSS技术实现
  •       行为,指的是页面中元素与输入设备交互的响应。一般使用javascript技术实现
  • web静态工程创建html文件

     html文件右键run即可

Tomcat

     由Apache组织提供的一种Web服务器,提供对jsp和Servlet的支持。它是一种轻量级的javaWeb容器(服务器),也是当前应用最广的JavaWeb服务器(免费)。

tomcat安装与环境配置

节省时间,直接借别人的笔记了

tomcat安装教程

创建一个javaweb项目并且添加tomcat配置

1.左上角新建项目,名字自定

d0f8b0d7958f470f892a4bbafc86b0a9.png

2.右键选择添加框架支持,勾选Web应用程序-确定

3.建立成功页面,多了web文件夹

03e0cffad1014edab8643d23294c657b.png

 4.给项目添加tomcat

     1.点击添加配置文件

e8dd2d4268914cebab67baa1c17a1e14.png     2.点击这个+

28283798ebda424da2415d4bdbced4c2.png

     3.选择这个tomcat的本地

注意:是Tomcat服务器,不是TomEE服务器

d5ac5ff6ff5c4e9daf1859cc34e5228d.png

     4.点击配置-----然后点击+号

6ef158cf86e54c89a25e40ba2d077c2f.png

如果是第一次配置的小伙伴可以看下面的这个额外步骤

 额外步骤:如果是第一次配置的,会出现这个界面,然后在里面填入tomcat的文件夹位置就好

256d7cea5efc44dfbb78077d23157d3b.png
     5.点击这个主目录的选择文件夹

4abfc4ac65bc4bd3a790b0530e17a347.png      6.选择自己tomcat的解压包位置---确定

注意:这个选择的包是bin包的上一级包那个才是

 选择正确的界面

1df35b2a1d47450ea62f8d8bc1f763e5.png

f8c98c34295446a9974ed2ae1401650a.png       7.点击修复,idea会自动帮忙配置工件

       8.在自动跳出来的页面点击应用--确定

43e43060591c48c18cd00c40d11983bb.png         9.点击这个运行按钮

1ea5a5a88aee45818c167122a1477468.png         10.跳出来这个界面就是部署安装成功(如果是404,那就是一些idea版本不带index.jsp或者没有这个文件,自己创建一个就可以了)
79b0cbc306cc4dcb927bd29581457c52.png

 tomcat乱码问题参考

创建动态工程

f77920306666486183a50e79bf1b2e83.png

 d2b6c71d30dd4a1783f7567ba4987296.png

7bd7bce2be2b4f27886f5d70b1fee999.png

web工程目录介绍

0429ed0cc5a14dbdb0411cfc2f8df332.png

 将创建的动态模块部署到tomcat中

尝试创建多个模块分别部署到tomcat以作区分

3c9c24524d6b43fcabd3d533e5a3afca.png

点击编辑配置

23bddf63013848208141d9aed50ad4b3.png

 服务器的名称设置成与项目模块相关,更好识别

在部署中添加要运行的项目模块,应用程序上下文是项目运行路径

e72cf1d497104f97835fdde631bae75c.png

 两个项目模块分别配置好之后就会有如上两个运行配置可供选择,切换运行之前,需要先停止上一次的运行。

给动态web工程添加额外jar包

0d18aee2986f426d8cf3c1b144012eb6.png

 2、添加你你类库需要的jar包文件。

c584aec828f546bd86ce25782c27c021.png

3、选择你添加的类库,给哪个模块使用:

fd0f0366814c4074a0046d18650a58d0.png

4、选择Artifacts选项,将类库,添加到打包部署中: 

74e5cf3e901945f6ac696dd613450451.png

jar包需要外部下载引入

热部署

tomcat中实现热部署(class修改不用重启服务器)

进行上面操作之后,页面只需要刷新即可得到修改之后的页面

xml详解

在生活中,我们经常会遇到一些存在关联的数据,又比如说在数据结构中的树结构,或者说中国有很多省份,每个省份又有很多城市,这些城市可以用一张树状图来表示,但是对于程序而言,解析树结构是非常困难的,这时采用XML文件保存这种具有树状结构的数据是最好的选择。

​ XML是Extensible Markup Language的缩写,是一种类似于HTML的标记语言,称为可标记扩展语言,而HTML称为超文本标记语言。而这里所谓的扩展,指的是用户可以按照XML规则自定义标记。

<?xml version="1.0" encoding="UTF-8"?>
<中国>
    <浙江>
        <城市>杭州</城市>
        <城市>金华</城市>
    </浙江>
    <河南>
        <城市>南阳</城市>
        <城市>郑州</城市>
    </河南>
</中国>

作用

  1. 用来保存数据,而且这些数据具有自我描述性
  2. 它还可以做为项目或者模块的配置文件
  3. 还可以做为网络传输数据的格式(现在JSON为主)

创建一个xml文件,用来描述图书信息

图书有id属性表示唯一标识,书名,有作者,价格的信息

82e5323834d84a51a806094403a45f63.png

<!--xml声明version是版本的意思encoding是编码-->
<?xmlversion="1.0"encoding="UTF-8"?>
<books><!--这是xml注释-->
<book id="SN123123413241"><!--book标签描述一本图书id属性描述的是图书的编号-->
<name>java编程思想</name><!--name标签描述的是图书的信息-->
<author>华仔</author><!--author单词是作者的意思,描述图书作者-->
<price>9.9</price><!--price单词是价格,描述的是图书的价格-->
</book>
<book id="SN12341235123"><!--book标签描述一本图书id属性描述的是图书的编号-->
<name>葵花宝典</name><!--name标签描述的是图书的信息-->
<author>班长</author><!--author单词是作者的意思,描述图书作者-->
<price>5.5</price><!--price单词是价格,描述的是图书的价格-->
</book>
</books>

xml语法

1.文档声明

​       在一个完整的XML文档中,必须包含一个XML文档的声明,并且该声明必须位于文档的第一行,这个声明表示该文档是一个XML文档,以及遵循哪个XML版本的规范。

       <?xml 版本信息[编码信息] [文档独立性信息]?>

      文档声明以符号"<?“开头,以符号”?>“结尾,中间可以版本声明、编码信息以及文档独立信息。需要注意的是在”<“和”?“之间、”?“和”>“之间以及第一个”?"和xml之间不能有空格;另外中括号括起来的部分是可选的。

      <?xml version="1.0" encoding="UTF-8"? standalone="yes"?>

2.元素定义

​ 在XML文档中,主体内容都是由元素(Element)组成的。元素一般是由开始标记、属性、元素内容和结束标记构成,具体如下。

<城市>北京</城市>

​ 上面的示例中,"<北京>“就是XML文档中的标记,标记的地名也就是元素的名称。在一个元素中可以嵌套若干子元素。如果一个元素没有嵌套在其他元素内,则这个元素称为根元素。根元素是XML文档定义的第一个元素。如果一个元素中没有嵌套子元素,也没有包含文本内容,这样的元素称为空元素,空元素可以不使用结束标记。但必须在起始标记的”>“前增加一个正斜杠”/"来说明该元素是一个空元素,例如:<img></img>可以简写成<img/>

3.属性定义

​    在XML文档中,可以为元素定义属性。属性是对元素的进一步描述和说明。在一个元素中,可以有多个属性,并且每个属性都有自己的名称和取值,具体如下:

   <零售价 单位="元">54.2</零售价>

​    在上面的示例中,<售价>元素中定义了一个属性“单位”。需要注意的是,在XML文档中,属性的命名规范同元素相同,属性值必须用双引号("")或者单引号(‘’)引起来,否则被视为错误。

4.注释

    如果想在XML文档中插入一些附加信息,比如作者姓名、地址和电话等信息,或者想暂时屏蔽某些XML语句,这时可以通过注释的方式实现,被注释的内容会被程序忽略而不被解析和处理,XML的注释和HTML注释写法基本一致,具体方法如下:

    <!--注释信息-->

severlet

javaweb三大组件

Servlet程序  Filter过滤器  Listener监听器

      Servlet是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。

创建一个servlet工程

继承servlet类

1.先创建动态工程

2.文件->项目结构

3.f55cce88405344f1b5dac7a513d62773.png

 89bff280a7694da59d55be59f04a5f48.png

 应用之后,点击确定

  4.servlet程序

public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)throws ServletException, IOException {
        System.out.println("HelloServlet被访问了");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

5.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标签给Tomcat配置Servlet程序-->
    <servlet><!--servlet-name标签Servlet程序起一个别名(一般是类名)-->
        <servlet-name>HelloServlet</servlet-name>
        <!--servlet-class是Servlet程序的全类名-->
        <servlet-class>alva.HelloServlet</servlet-class>
    </servlet>
    <!--servlet-mapping标签给servlet程序配置访问地址-->
    <servlet-mapping><!--servlet-name标签的作用是告诉服务器,我当前配置的地址给哪个Servlet程序使用-->
        <servlet-name>HelloServlet</servlet-name>
        <!--url-pattern标签配置访问地址<br/>/斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径<br/>/hello表示地址为:http://ip:port/工程路径/hello<br/>-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

思路是先配置程序,再配置地址

   我们选择服务器访问之后运行的是index.jsp页面,想要访问servlet程序的话就输入对应的工程路径

7f1a7b049a61451cb6c27d4fbd963f60.png

 a09dd92f89414aa99adae002a0e2ed71.png

c8909b6a42ee4217a8e141bb0209ee94.png

 url地址到Servlet程序的访问

8edbe0f105a544c580865e3c74b54184.png

Servlet的生命周期

     以下第一、二步,是在第一次访问,的时候创建Servlet程序会调用。第三步每次访问都会调用。第四步,在web工程停止的时候调用。

  1. 执行Servlet构造器方法
  2. 执行init初始化方法。
  3. 执行service方法
  4. 执行destroy销毁方法

e85ba56114f148ce934fb5ff75e3ebb4.png

 GET和POST请求的分发处理

    service方法是专门用来处理请求和响应的

做一个get请求

 @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse)throws ServletException, IOException {
        System.out.println("3service===HelloServlet被访问了");
        //类型转换(因为它有getMethod()方法)
        HttpServletRequest httpServletRequest= (HttpServletRequest) servletRequest;
        //获取请求的方式
        String method = httpServletRequest.getMethod();
        if("GET".equals(method)){
            doGet();
        }else if("POST".equals(method)){
            doPost();
    }
    }

  /**
     * 做get请求的操作
     **/
    public void doGet(){
        System.out.println("get请求");
        System.out.println("get请求");
    }
    /**
     *做post请求的操作
     **/
    public void doPost(){
        System.out.println("post请求");
        System.out.println("post请求");
    }

tohello.html

   <form action="http://localhost:8099/server/hello" method="get">
      <input type="submit">
   </form>

ef7e5c43f29241948d9eea48d3f0d799.png

 访问 http://localhost:8099/server/tohello.html 点击按钮之后,控制台输出

edd55cf53ec14ffc8294f65f00cfb9dd.png

 将method的get改成post之后在运行操作得到的结果如下

f45d4de4eb3744429ac332e7537987a0.png

通过继承HttpServlet实现Servlet程序

一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序。

  1. 编写一个类去继承HttpServlet类
  2. 根据业务需要重写doGet或doPost方法
  3. 到web.xml中的配置Servlet程序的访问地址
public class servlethaha extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("do get");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("do post");
    }
}

访问 http://localhost:8099/server/hello1  改成post同理

deb03227341240d5a9fe1af3a853c5dc.png

 创建servlet程序有快捷方式,因为我用的是新版的idea2022,不同的idea可能方法不一致

idea创建Servlet

2022IntelliJ IDEA 创建Servlet

Servlet类的继承体系

0b51e05b5e584d6d85a6e42ef173ae80.png

ServletConfig类

     ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类。

     Servlet程序和ServletConfig对象都是由Tomcat负责创建,我们负责使用。Servlet程序默认是第一次访问的时候创建,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象。

ServletConfig类的三大作用

  1. 可以获取Servlet程序的别名servlet-name的值
  2. 获取初始化参数init-param
  3. 获取ServletContext对象 
   <servlet>
        <servlet-name>servlet</servlet-name>
        <servlet-class>alva.servlet</servlet-class>
        <!-- 初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:3306/alva</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
public class servlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        //1、可以获取Servlet程序的别名servlet-name的值
        System.out.println("HelloServlet程序的别名是:"+config.getServletName());
        //2、获取初始化参数init-param
        System.out.println("初始化参数username的值是;"+config.getInitParameter("username"));
        System.out.println("初始化参数url的值是;"+config.getInitParameter("url"));
        //3、获取ServletContext对象
        System.out.println(config.getServletContext());
    }
}

466bf6f56e824e2d9b0939e9da94c389.png

ServletContext类

      什么是ServletContext?

  • ServletContext是一个接口,它表示Servlet上下文对象
  • 一个web工程,只有一个ServletContext对象实例
  • ServletContext对象是一个域对象
  • ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁

      什么是上下文对象?

     上下文对象是服务器容器的全局变量,部署后,启动Tomcat时,Tomcat将为每一个应用创建一个对象,这个对象称之为上下文对象

      什么是域对象?

  • 域对象,是可以像Map一样存取数据的对象,叫域对象。
  • 这里的域指的是存取数据的操作范围,整个web工程。
存数据取数据删除数据
Mapput()get()remove()
域对象setAttribute()getAttribute()removeAttribute()

ServletContext类的四个作用

  • 获取web.xml中配置的上下文参数context-param
  • 获取当前的工程路径,格式:/工程路径
  • 获取工程部署后在服务器硬盘上的绝对路径
  • 像Map一样存取数据
   <!--context-param是上下文参数,它属于整个web工程,配置的时候放webapp标签内-->
    <context-param>
        <param-name>username</param-name>
        <param-value>alva</param-value>
    </context-param>
    <context-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
    </context-param>
public class ServletContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、获取web.xml中配置的上下文参数context-param
        jakarta.servlet.ServletContext context = getServletConfig().getServletContext();
        String username=context.getInitParameter("username");
        System.out.println("context-param参数username的值是:"+username);
        System.out.println("context-param参数password的值是:"+context.getInitParameter("password"));
        //2、获取当前的工程路径,格式:/工程路径
        System.out.println("当前工程路径:"+context.getContextPath());
        //3、获取工程部署后在服务器硬盘上的绝对路径/***/斜杠被服务器解析地址为:http://ip:port/工程名/映射到IDEA代码的web目录<br/>*/
        System.out.println("工程部署的路径是:"+context.getRealPath("/"));
        System.out.println("工程下css目录的绝对路径是:"+context.getRealPath("/css"));
        System.out.println("工程下imgs目录1.jpg的绝对路径是:"+context.getRealPath("/imgs/1.jpg"));
    }
}

acaaba4e360f42619f37b5919dbc9b54.png

 存取数据

 System.out.println("保存之前:Context1获取key1的值是:"+context.getAttribute("key1"));
        context.setAttribute("key1","value1");
        System.out.println("Context1中获取域数据key1的值是:"+context.getAttribute("key1"));

a408927f6191476db8fe02c9a190fb34.png

     在其他含有ServletContext对象的servlet类中也可以获取

HTTP协议

     什么是协议?

    协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。

  • HTTP协议中的数据又叫报文。
  • 请求的HTTP协议格式客户端给服务器发送数据叫请求。
  • 服务器给客户端回传数据叫响应。
  • 请求又分为GET请求,和POST请求两种

      GET请求

请求行

请求的方式                       GET

请求的资源路径                [+?+请求参数]

请求的协议的版本号         HTTP/1.12

请求头

key:value       组成不同的键值对,表示不同的含义。

391fc12ff8264b17afa2d7a039c1f82b.png

     POST请求

请求行

请求的方式                POST

请求的资源路径         [+?+请求参数]

请求的协议的版本号  HTTP/1.12

请求头

key:value      不同的请求头,有不同的含义空行

请求体===>>>就是发送给服务器的数据

3268eac5b58d4b6faa27e79d0c8d1640.png

 常用请求头的说明

  • Accept: 表示客户端可以接收的数据类型
  • Accpet-Languege: 表示客户端可以接收的语言类型
  • User-Agent: 表示客户端浏览器的信息
  • Host:表示请求时的服务器ip和端口号

     哪些是GET请求,哪些是POST请求GET请求有哪些:

  1. form标签method=get
  2. a标签
  3. link标签引入css
  4. Script标签引入js文件
  5. img标签引入图片
  6. iframe引入html页面

     在浏览器地址栏中输入地址后敲回车POST请求有哪些:

  1. form标签method=post

响应的HTTP协议格式

响应行

(1)响应的协议和版本号

(2)响应状态码

(3)响应状态描述符

响应头

key:value不同的响应头,有其不同含义

空行

响应体---->>>就是回传给客户端的数据

9fd67fe861b44d21818c2c5157845cb9.png

常用的响应码说明

  • 200     表示请求成功
  • 302     表示请求重定向
  • 404     表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
  • 500     表示服务器已经收到请求,但是服务器内部错误(代码错误)
  • 405     提交方式是POST,在httpservlet里没有dopost方法

MIME类型说明

      MIME是HTTP协议中数据类型。MIME的英文全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。

常见的MIME类型:

d23c63f023484314bd1dfb8dcd12ff39.png

谷歌浏览器如何查看HTTP协议:

83ac925286564b799dff9bbb707e577e.png

火狐浏览器如何查看HTTP协议: 

8d5a5440209545019a064aa3c87c3721.png

 HttpServletRequest类

        每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获取到所有请求的信息。

HttpServletRequest类的常用方法

  • i.getRequestURI()               获取请求的资源路径
  • ii.getRequestURL()             获取请求的统一资源定位符(绝对路径)
  • iii.getRemoteHost()             获取客户端的ip地址
  • iv.getHeader()                     获取请求头
  • v.getParameter()                 获取请求的参数
  • vi.getParameterValues()     获取请求的参数(多个值的时候使用)
  • vii.getMethod()                    获取请求的方式GET或POST
  • viii.setAttribute(key,value);  设置域数据
  • ix.getAttribute(key);             获取域数据
  • x.getRequestDispatcher()   获取请求转发对象
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("do get");
//        获取请求的资源路径
        System.out.println("uri =>" + req.getRequestURI());
//        获取请求的统一资源定位符 (绝对路径)
        System.out.println("url =>" + req.getRequestURL());
//        getRemoteHost()获取客户端的ip地址
        System.out.println("客户端ip地址=>"+req.getRemoteHost());
//        iv.getHeader()获取请求头
        System.out.println("请求头User-Agent==>>"+req.getHeader("User-Agent"));
//        getMethod()获取请求的方式GET或POST
        System.out.println("请求的方式==>>"+req.getMethod());
    }

67ade483550a4dfaae0d2893783a595a.png

编写程序获取请求参数

前台表单

   <form action="http://localhost:8099/server/hello" method="get">
       用户名:<input type="text" name="username"><br/>
       密码:<input type="password" name="password"><br/>
       兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
               <input type="checkbox" name="hobby" value="java">Java
               <input type="checkbox" name="hobby" value="js">JavaScript<br/>
       <input type="submit">
   </form>

Java代码

public class helloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求参数
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        String[] hobby=req.getParameterValues("hobby");

        System.out.println("用户名:"+username);
        System.out.println("密码:"+password);
        System.out.println("兴趣爱好:"+ Arrays.asList(hobby));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("do post");
    }
}

7afc6281238f4d6daccc9343f17649eb.png

 乱码解决

731e67385594416d989b49fb2da8baff.png

 请求转发

   请求转发是指,服务器收到请求后,从一次资源跳转到另一个资源的操作叫请求转发。

8b1ec934837844e4a92091ea6b67f0d2.png

 编程实现

d52ad1454f53475fa5d812a16200d112.png

 5ddd1934d3cd47d59f8fce3882e1a4a1.png

 base标签的作用

4b5ede49a5ba4711b3e483fe8c30566a.png

fc5ebba715ba4c939dfb67c124afde18.png

     怎么理解呢?就是base标签是放在头部标签中的,用来设置相对路径,在body中,发生页面跳转时的路径都是按照这个相对跳转的

     上面提到的请求转发,就是用servlet程序设置请求转发到要设置的路径,前台设置跳转到servlet路径

Web中的相对路径和绝对路径

3a72d3714b114302a4691ff4c5085def.png

 web中/斜杠的不同意义

04b76d5a6deb41eab1df7977155e8594.png

HttpServletResponse类

      HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。

      HttpServletRequest表示请求过来的信息,HttpServletResponse表示所有响应的信息

      我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置

两个输出流的说明

字节流  getOutputStream();       常用于下载(传递二进制数据)

字符流  getWriter();                    常用于回传字符串(常用)

两个流同时只能使用一个。使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。

编程实现

  PrintWriter writer = resp.getWriter();
  writer.write("给客户端传字符串");

68c51842bfa749ecb7f78d198a294780.png

响应的乱码解决 

//它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
        //此方法一定要在获取流对象之前调用才有效
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        writer.write("给客户端传字符串");

31fe8fd24c7148e994d0100056d65463.png

请求重定向

      请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)

f4645ade317f4e41b7a9a7d7c453a4e2.png

resp.sendRedirect("http://localhost:8080"); 

请求转发和重定向的区别

f879bff7e6ab4599b12925ccb0e3fbd5.png

转发是指当前Servlet将请求转交给其他的Servlet进行再次处理

转发特点:

  1.   转发时浏览器只发送1次请求
  2.   转发是在服务器端进行的
  3.   转发时浏览器的地址栏没有发生改变
  4.   浏览器感知不到转发的发生

重定向
 重定向是Servlet发送给浏览器的一个特殊的响应,这个响应告诉浏览器再去请求另一个地址,类似于政府的相关部门,该特殊响应的报文格式如下:

HTTP/1.1 302 Found
Location: http://localhost:8080/04_WEB_Servlet/target.html

 这个特殊响应的响应状态码是302,还有一个特殊的响应头Location指向的是一个新的地址,当浏览器收到302这个响应状态码以后,就会自动的再次向Location所指向的地址发送请求
重定向的特点:

  1.   重定向时浏览器一共发送了2次请求
  2.   重定向是在浏览器端进行的
  3.   浏览器的地址栏会发生改变
  4.   浏览器可以感知到重定向的发生

页面跳转的时候什么时候用转发,什么时候用重定向

  • 如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。

  • 剩下所有的请求均使用重定向。(重定向使用较多。)

转发带来的问题

    如果最后一次转发的是一次提交,那么每一次刷新由于没有跳转的正确的页面都会重新提交,最终导致重复提交

  • 删除之后,重定向

  • 修改之后,重定向

  • 保存之后,重定向

  • 重定向:

    • 成功

    • 失败

转发和重定向的比较:

比较内容转发重定向
浏览器请求次数12
发生的位置服务器浏览器
地址栏变化
浏览器感知

1

111

 JSP

   JSP(全称Java Server Pages)是由Sun公司专门为了解决动态生成HTML文档的技术

     jsp以java基础开发。所以它沿用了java强大的api功能,jsp页面中的html代码用来显示静态内容的部分,嵌入到页面中的Java代码与jsp标记来生成动态的内容部分

Servlet程序输出html页面

    学习jsp技术之前,如果我们要往客户端输出一个页面。我们可以使用Servlet程序来实现。具体的代码如下

31ea51fd9c0c4e8385374a4e5714d2c6.png

在浏览器中输入访问Servlet的程序地址得到以下结果

348da5168013425f84afd793932f9c21.png

     通过Servlet输出简单的html页面信息都非常不方便。那我们要输出一个复杂页面的时候,就更加的困难,而且不利于页面的维护和调试。所以sun公司推出一种叫做jsp的动态页面技术帮助我们实现对页面的输出繁锁工作。

      jsp页面的访问千万不能像HTML页面一样。托到浏览器中。只能通过浏览器访问Tomcat服务器再访问jsp页面

jsp文件的创建

在web目录下面右键创建即可,和html文件运行的方式一样

jsp运行原理

  jsp的本质,其实是一个Servlet程序。

使用tomcat运行之后,jsp文件会生成对应的java类文件,打开文件查看里面的内容:发现,生成的类继承于HttpJspBase类。这是一个jsp文件生成Servlet程序要继承的基类

HttpJspBase这个类就是所有jsp文件生成Servlet程序需要去继承的基类。并且这个HttpJspBase类继承于HttpServlet类。所以jsp也是一个Servlet小程序

3a231425b890455683e16cb601b3cf69.png

4b17f90e59fc4ff5a7c00184a207c6bd.png

jsp的语法

jsp文件头部声明介绍(page指令介绍)

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

这是jsp文件的头声明。表示这是jsp页面。language属性值只能是java。

1faf2af94afd4715b583d1a5c0a68797.png

jsp的三种脚本

声明脚本

<%!
  java代码
%>
  1. 我们可以定义全局变量
  2. 定义static静态代码块
  3. 定义方法
  4. 定义内部类
  5. 几乎可以写在类的内部写的代码,都可以通过声明脚本来实现

e7e745b6009c402eb1feff255f94e111.png

表达式脚本

<%= 表达式 %>

表达式脚本用于向页面输出内容

表达式脚本翻译到Servlet程序的service方法中以out.print()打印输出 out是jsp的一个内置对象,用于生成html的源代码

注意:表达式不要以分号结尾,否则会报错表达式脚本可以输出任意类型。组成“<%=”标记的各字符之间不可以有空格

比如:1.输出整型2.输出浮点型3.输出字符串4.输出对象

42d8f1dc6db348cea560bfe5bce0867a.png

 代码脚本

<% java代码 %>
  • 代码脚本里可以书写任意的java语句
  • 代码脚本的内容都会被翻译到service方法中
  • 所以service方法中可以写的java代码,都可以书写到代码脚本中

278ec7feabac4089ae0946a58502ae10.png

 jsp注释

<%--jsp注释--%>

隐式注释

    JSP 隐藏注释在 JSP 源代码中,它不会被 JSP 引擎处理,也不会在客户端的 Web 浏览器上显示,格式如下:

  •   <%--comment--%>
  •  <% 行注释 %>
  •  <% /*   块注释    */      %>   

jsp九大内置对象

  • request对象:    是 javax.servlet.httpServletRequest类型的对象。
  • response对象: 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。
  • session对象:    是由服务器自动创建的与用户请求相关的对象。
  • application对象:可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。
  • out 对象:           用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。
  • pageContext 对象:作用是取得任何范围的参数,可以获取 JSP页面的out、request、reponse、session、application 等对象。
  • config 对象:     主要作用是取得服务器的配置信息。
  • page 对象:       代表JSP本身,只有在JSP页面内才是合法的。
  • exception 对象:作用是是显示异常信息,只有在包含 isErrorPage="true" 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。

九大内置对象,都是我们可以在【代码脚本】中或【表达式脚本】中直接使用的对象。

jsp四大域对象

四大域对象经常用来保存数据信息。

  • pageContext    可以保存数据在同一个jsp页面中使用
  • request             可以保存数据在同一个request对象中使用。经常用于在转发的时候传递数据session             可以保存在一个会话中使用
  • application(ServletContext)     就是ServletContext对象

新建两个jsp页面来测试

<body>
   测试四大域对象 <br>
   <%
       //设置page域的数据
       pageContext.setAttribute("key","pageContext-value");
       //设置request域的数据
       request.setAttribute("key","request-value");
       //设置session域的数据
       session.setAttribute("key","session-value");
       //设置application域的数据
       application.setAttribute("key","application-value");
   %>
    <%--测试当前页面的作用域--%>
      <%=pageContext.getAttribute("key")%><br>
      <%=request.getAttribute("key")%><br/>
      <%=session.getAttribute("key")%><br/>
      <%=application.getAttribute("key")%><br/>
</body>
<body>
         这是context2页面<br/>
         <%=pageContext.getAttribute("key")%><br/>
         <%=request.getAttribute("key")%><br/>
         <%=session.getAttribute("key")%><br/>
         <%=application.getAttribute("key")%><br/>
</body>

1de397b4e9f54e84bd6b5a6944b65461.png

out输出流和response.getwriter()输出流 

<body>
   测试四大域对象 <br>
   <%
       //out输出
       out.write("这是out的第一次输出<br/>");
       //out flush之后。会把输出的内容写入writer的缓冲区中
       out.flush();
       //最后一次的输出,由于没有手动flush,会在整个页面输出到客户端的时候,自动写入到writer缓冲区
       out.write("这是out的第二次输出<br/>");
       //writer的输出
       response.getWriter().write("这是writer的第一次输出<br/>");
       response.getWriter().write("这是writer的第二次输出<br/>");
   %>

</body>

c5004fad71c84c108c29f60929c63139.png

图解out流和writer流的两个缓冲区如何工作

c85f41a504ef4f1aa9c490887d238a8d.png

 将out.flush注释之后再运行

025581793ea040f18c8ae88895369281.png

 JSP7 个 动作指令

  • jsp:forward: 执行页面转向,将请求的处理转发到下一个页面。
  • jsp:param: 用于传递参数,必须与其他支持参数曲标签一起使用。
  • jsp:include: 用于动态引入一个 JSP 页面。
  • jsp:pugin: 用于下载 JavaBean 或 Applet 到客户端执行。
  • jsp:useBean: 使用 JavaBean。
  • jsp:setProperty: 修改 JavaBean 实例的属性值。
  • jsp:getProperty: 获取 JavaBean 实例的属性值。

jsp常用标签

静态包含

<%@ include file="index.jsp" %>

   静态包含是把包含的页面内容原封装不动的输出到包含的位置

3226a25ff410423eadbefdac7cc8cd0d.png

动态包含--很少用

<jsp:include page=""></jsp:include>

    动态包含会把包含的jsp页面单独翻译成servlet文件,然后在执行到时候再调用翻译的servlet程序。并把计算的结果返回。

     动态包含是在执行的时候,才会加载。所以叫动态包含。

页面转发--常用

<jsp:forward page=""></jsp:forward>

转发功能相当于 request.getRequestDispatcher("/xxxx.jsp").forward(request,response);的功能。

静态包含和动态包含的区别

5f552d1cbdb64aa7bab4867c00f41fb1.png

       在这里需要补充说明一点:我们在工作中,几乎都是使用静态包含。理由很简单。因为jsp页面虽然可以写java代“玩转”Java系列码,做其他的功能操作。但是由于jsp在开发过程中被定位为专门用来展示页面的技术。也就是说。jsp页面中,基本上只有html,css,js。还有一些简单的EL,表达式脚本等输出语句。所以我们都使用静态包含 

Listener监听器

监听器就是实时监视一些事物状态的程序,我们称为监听器

ServletContextListener监听器

javax.servlet.ServletContextListener   ServletContext监听器

监听器的使用步骤

第一步:我们需要定义一个类。然后去继承生命周期的监听器接口。

第二步:然后在Web.xml文件中配置。ServletContextListener监听器,一定要在web.xml文件中配置之后才会生效

<listener>
   <listener-class>全类名</listener-class>
</listener>

生命周期监听器两个方法

创建一个类实现ServletContextListener接口

public class listener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext对象被创建了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext对象被销毁了");
    }
}

web.xml配置

 <listener>
        <listener-class>alva.listener</listener-class>
    </listener>

服务器启动和停止时分别输入上面两句

JavaBean

JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:

  • 这个Java类必须具有一个无参的构造函数
  • 属性必须私有化。
  • 私有化的属性必须通过public类型的方法暴露给其它程序,并且方法的命名也必须遵守一定的命名规范。

javaBean示例

 1/**
 4  * @author gacl
 5  * Person类就是一个最简单的JavaBean
 6  */
 7 public class Person {
 8 
 9     //------------------Person类封装的私有属性---------------------------------------
10     // 姓名 String类型
11     private String name;
12     // 性别 String类型
13     private String sex;
14     // 年龄 int类型
15     private int age;
16     //是否已婚 boolean类型
17     private boolean married;
18     //---------------------------------------------------------
19     
20     //------------------Person类的无参数构造方法---------------------------------------
21     /**
22      * 无参数构造方法
23      */
24     public Person() {
25         
26     }
27     //---------------------------------------------------------
28     
29     //------------------Person类对外提供的用于访问私有属性的public方法---------------------------------------
30     public String getName() {
31         return name;
32     }
33 
34     public void setName(String name) {
35         this.name = name;
36     }
37 
38     public String getSex() {
39         return sex;
40     }
41 
42     public void setSex(String sex) {
43         this.sex = sex;
44     }
45 
46     public int getAge() {
47         return age;
48     }
49 
50     public void setAge(int age) {
51         this.age = age;
52     }
53 
54     public boolean isMarried() {
55         return married;
56     }
57 
58     public void setMarried(boolean married) {
59         this.married = married;
60     }
61     //---------------------------------------------------------
62 }

在JSP中使用JavaBean

JSP技术提供了三个关于JavaBean组件的动作元素,即JSP标签,它们分别为:

  • <jsp:useBean>标签:用于在JSP页面中查找或实例化一个JavaBean组件。
  • <jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
  • <jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。

   <jsp:useBean>标签

      用于在指定的域范围内查找指定名称的JavaBean对象如果存在则直接返回该JavaBean对象的引用,如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。 
  常用语法:
    <jsp:useBean id="beanName" class="package.class" scope="page|request|session|application"/>

  •   "id"属性用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称。
  •   "class"属性用于指定JavaBean的完整类名(即必须带有包名)。
  •   "scope"属性用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session和application等四个值中的一个,其默认值是page

使用范例

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--
 3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
 4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
 5     ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
 6     ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
 7     ┝class:此对象对应的包.类名称
 8     ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
 9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 <%
12     //person对象在上面已经使用jsp:useBean标签实例化了,因此在这里可以直接使用person对象
13     //使用setXxx方法为对象的属性赋值
14     //为person对象的name属性赋值
15     person.setName("孤傲苍狼");
16     //为person对象的Sex属性赋值
17     person.setSex("男");
18     //为person对象的Age属性赋值
19     person.setAge(24);
20     //为person对象的married属性赋值
21     person.setMarried(false);
22 %>
23 <!DOCTYPE HTML>
24 <html>
25   <head>
26     <title>jsp:useBean标签使用范例</title>
27   </head>
28   
29   <body>
30     <%--使用getXxx()方法获取对象的属性值 --%>
31     <h2>姓名:<%=person.getName()%></h2>
32     <h2>性别:<%=person.getSex()%></h2>
33     <h2>年龄:<%=person.getAge()%></h2>
34     <h2>已婚:<%=person.isMarried()%></h2>
35   </body>
36 </html>

 

 <jsp:setProperty>标签

           用于设置和访问JavaBean对象的属性。 
  语法格式一:
    <jsp:setProperty name="beanName" property="propertyName" value="string字符串"/>

  语法格式二:
    <jsp:setProperty name="beanName" property="propertyName" value="<%= expression %>" />

  语法格式三:
    <jsp:setProperty name="beanName" property="propertyName" param="parameterName"/>

  语法格式四:
    <jsp:setProperty name="beanName" property= "*" />

  •   name属性用于指定JavaBean对象的名称。 
  •   property属性用于指定JavaBean实例对象的属性名
  •   value属性用于指定JavaBean对象的某个属性的值,value的值可以是字符串,也可以是表达式。为字符串时,该值会自动转化为JavaBean属性相应的类型,如果value的值是一个表达式,那么该表达式的计算结果必须与所要设置的JavaBean属性的类型一致。  
  •   param属性用于将JavaBean实例对象的某个属性值设置为一个请求参数值,该属性值同样会自动转换成要设置的JavaBean属性的类型。

<jsp:setProperty>标签使用范例1:使用jsp:setProperty标签设置person对象的属性值

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--
 3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
 4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
 5     ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
 6     ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
 7     ┝class:此对象对应的包.类名称
 8     ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
 9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 
12 <%--
13 使用jsp:setProperty标签设置person对象的属性值
14 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型
15 但是jsp:setProperty对于复合数据类型无法自动转换
16 --%>
17 <jsp:setProperty property="name" name="person" value="白虎神皇"/>
18 <jsp:setProperty property="sex" name="person" value="男"/>
19 <jsp:setProperty property="age" name="person" value="24"/>
20 <jsp:setProperty property="married" name="person" value="false"/>
21 <%--
22 birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的
23 <jsp:setProperty property="birthday" name="person" value="1988-05-07"/>
24 --%>
25 <jsp:setProperty property="birthday" name="person" value="<%=new Date()%>"/>
26 <!DOCTYPE HTML>
27 <html>
28   <head>
29     <title>jsp:setProperty标签使用范例</title>
30   </head>
31   
32   <body>
33     <%--使用getXxx()方法获取对象的属性值 --%>
34     <h2>姓名:<%=person.getName()%></h2>
35     <h2>性别:<%=person.getSex()%></h2>
36     <h2>年龄:<%=person.getAge()%></h2>
37     <h2>已婚:<%=person.isMarried()%></h2>
38     <h2>出生日期:<%=person.getBirthday()%></h2>
39   </body>
40 </html>

 

<jsp:setProperty>标签使用范例2:使用请求参数为bean的属性赋值

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--
 3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
 4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
 5     ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
 6     ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
 7     ┝class:此对象对应的包.类名称
 8     ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
 9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 
12 <%--
13     jsp:setProperty标签可以使用请求参数为bean的属性赋值
14     param="param_name"用于接收参数名为param_name的参数值,然后将接收到的值赋给name属性
15 --%>
16 <jsp:setProperty property="name" name="person" param="param_name"/>
17 
18 <!DOCTYPE HTML>
19 <html>
20   <head>
21     <title>jsp:setProperty标签使用范例</title>
22   </head>
23   
24   <body>
25       <%--使用getXxx()方法获取对象的属性值 --%>
26        <h2>姓名:<%=person.getName()%></h2>
27   </body>
28 </html>

<jsp:setProperty>标签使用范例3:用所有的请求参数为bean的属性赋值

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--
 3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
 4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
 5     ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
 6     ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
 7     ┝class:此对象对应的包.类名称
 8     ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
 9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 
12 <%--
13     jsp:setProperty标签用所有的请求参数为bean的属性赋值
14     property="*"代表bean的所有属性
15 --%>
16 <jsp:setProperty property="*" name="person"/>
17 
18 <!DOCTYPE HTML>
19 <html>
20   <head>
21     <title>jsp:setProperty标签使用范例</title>
22   </head>
23   
24   <body>
25     <%--使用getXxx()方法获取对象的属性值 --%>
26     <h2>姓名:<%=person.getName()%></h2>
27     <h2>性别:<%=person.getSex()%></h2>
28     <h2>年龄:<%=person.getAge()%></h2>
29   </body>
30 </html>

 

<jsp:getProperty>标签

  用于读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的响应正文中。
  语法:
      <jsp:getProperty name="beanInstanceName" property="PropertyName" />

  •     name属性用于指定JavaBean实例对象的名称,其值应与<jsp:useBean>标签的id属性值相同。 
  •     property属性用于指定JavaBean实例对象的属性名。

  如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容为“null”的字符串。

范例:使用jsp:getProperty获取bean对象的属性值

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--
 3 在jsp中使用jsp:useBean标签来实例化一个Java类的对象
 4 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
 5     ┝<jsp:useBean>:表示在JSP中要使用JavaBean。
 6     ┝id:表示生成的实例化对象,凡是在标签中看见了id,则肯定表示一个实例对象。
 7     ┝class:此对象对应的包.类名称
 8     ┝scope:此javaBean的保存范围,四种范围:page、request、session、application
 9 --%>
10 <jsp:useBean id="person" class="gacl.javabean.study.Person" scope="page"/>
11 
12 <%--
13 使用jsp:setProperty标签设置person对象的属性值
14 jsp:setProperty在设置对象的属性值时会自动把字符串转换成8种基本数据类型
15 但是jsp:setProperty对于复合数据类型无法自动转换
16 --%>
17 <jsp:setProperty property="name" name="person" value="白虎神皇"/>
18 <jsp:setProperty property="sex" name="person" value="男"/>
19 <jsp:setProperty property="age" name="person" value="24"/>
20 <jsp:setProperty property="married" name="person" value="false"/>
21 <%--
22 birthday属性是一个Date类型,这个属于复合数据类型,因此无法将字符串自动转换成Date ,用下面这种写法是会报错的
23 <jsp:setProperty property="birthday" name="person" value="1988-05-07"/>
24 --%>
25 <jsp:setProperty property="birthday" name="person" value="<%=new Date()%>"/>
26 <!DOCTYPE HTML>
27 <html>
28   <head>
29     <title>jsp:getProperty标签使用范例</title>
30   </head>
31   
32   <body>
33     <%--使用jsp:getProperty标签获取对象的属性值 --%>
34     <h2>姓名:<jsp:getProperty property="name" name="person"/></h2>
35     <h2>性别:<jsp:getProperty property="sex" name="person"/></h2>
36     <h2>年龄:<jsp:getProperty property="age" name="person"/></h2>
37     <h2>已婚:<jsp:getProperty property="married" name="person"/></h2>
38     <h2>出生日期:<jsp:getProperty property="birthday" name="person"/></h2>
39   </body>
40 </html>

jsp指令(伪指令)

jsp中有三大指令,分别是:

  • page指令,最复杂,也是最常用的
  • include —>静态包含,这个和requestDispatcher.include区别是后者是动态包含
  • taglib -->导入标签库

在jsp文件中使用指令的格式为:<%@指令名 属性名=属性值 %>

EL表达式

  Expression Language。是表达式语言。

EL表达式的什么作用:

        EL表达式主要是代替jsp页面中的表达式脚本在jsp页面中进行数据的输出。因为EL表达式在输出数据的时候,要比jsp的表达式脚本要简洁很多。

 <%
       request.setAttribute("a","哈哈哈");
 %>
       表达式脚本输出key的值是:
 <%= request.getAttribute("a") == null ?"" :request.getAttribute("a") %> <br>
       EL表达式输出key的值是:
 ${a}

    EL表达式在输出null值的时候,输出的是空串。jsp表达式脚本输出null值的时候,输出的是null字符串

EL表达式搜索域数据的顺序

     EL表达式主要是在jsp页面中输出数据。主要是输出域对象中的数据。当四个域中都有相同的key的数据的时候,EL表达式会按照四个域的从小到大的顺序去进行搜索,找到就输出。

    page - request - session - application

   <%
      //往四个域中都保存了相同的key的数据。
      request.setAttribute("key","request");
      session.setAttribute("key","session");
      application.setAttribute("key","application");
      pageContext.setAttribute("key","pageContext");
    %>
    ${key}

最先输出的是 pageContext

输出Bean的普通属性,数组属性。List集合属性,map集合属性

   需求——输出Person类中普通属性,数组属性。list集合属性和map集合属性

public class Student {
//    需求——输出Person类中普通属性,数组属性。list集合属性和map集合属性
    private String name;
    private String[] phones;
    private List<String> cities;
    private Map<String,Object> map;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getPhones() {
        return phones;
    }

    public void setPhones(String[] phones) {
        this.phones = phones;
    }

    public List<String> getCities() {
        return cities;
    }

    public void setCities(List<String> cities) {
        this.cities = cities;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public int getAge(){
        return 18;
    }
}
<%

  Student student = new Student();
  student.setName("alva");
  student.setPhones(new String[]{"123214","1245314","23412412"});

  List<String> cities = new ArrayList<String>();
  cities.add("北京");
  cities.add("上海");
  cities.add("深圳");
  student.setCities(cities);

  Map<String,Object> map = new HashMap<>();
  map.put("a","a");
  map.put("b","b");
  map.put("c","c");
  student.setMap(map);

  pageContext.setAttribute("p",student);
%>
  输出Student:${p}<br/>
  输出Student的name属性:${p.name}<br>
  输出Student的pnones数组属性值:${p.phones[2]}<br>
  输出Student的cities集合中的元素值:${p.cities}<br>
  输出Student的List集合中个别元素值:${p.cities[2]}<br>
  输出Student的Map集合:${p.map}<br>
  输出Student的Map集合中某个key的值:${p.map.c}<br>
  输出Person的age属性:${p.age}<br>

e10e8d986daa4dd293f648749f2831a9.png

 EL表达式运算

 关系运算

a60293c1eab746348f4e3d55cf2375c1.png

逻辑运算

02cb2e97eae74e0a9df3f1c2e44e7e9d.png

算数运算

5768cecf515e41249f9441f6cd6afebb.png

empty运算

empty运算可以判断一个数据是否为空,如果为空,则输出true,不为空输出false。

以下几种情况为空:

  • 值为null值的时候,为空
  • 值为空串的时候,为空
  • 值是Object类型数组,长度为零的时候
  • list集合,元素个数为零
  • map集合,元素个数为零

“.”点运算和[]中括号运算符

   .点运算,可以输出Bean对象中某个属性的值。[]中括号运算,可以输出有序集合中某个元素的值。并且[]中括号运算,还可以输出map集合中key里含有特殊字符的key的值

<html>
  <head>
    <title>index</title>
  </head>
  <body>
  <%
    Map<String,Object>map=new HashMap<String,Object>();
    map.put("a.a.a","aaaValue");
    map.put("b+b+b","bbbValue");
    map.put("c-c-c","cccValue");
    request.setAttribute("map",map);
  %>${map['a.a.a']}<br>
  ${map["b+b+b"]}<br>
  ${map['c-c-c']}<br>
  </body>
</html>

 EL表达式的11个隐含对象

EL个达式中11个隐含对象,是EL表达式中自己定义的,可以直接使用

10d4355862c748eb8088f6cef753d894.png

05ab2c9ca9ca46b58f3841d0355f979f.png

EL获取四个特定域中的属性

7b1414f49d6743a6ad50a82305fb4284.png

 <%
       pageContext.setAttribute("key1","pageContext1");
       pageContext.setAttribute("key2","pageContext2");
       request.setAttribute("key2","request");
       session.setAttribute("key2","session");
       application.setAttribute("key2","application");
     %>
        ${applicationScope.key2}

 输出 application

pageContext对象的使用

<html>
<head>
    <title>index</title>
</head>
<body>
<%
    pageContext.setAttribute("req", request);
%>
<%=request.getScheme()%><br>
1.协议:${req.scheme}<br>
2.服务器ip:${pageContext.request.serverName}<br>
3.服务器端口:${pageContext.request.serverPort}<br>
4.获取工程路径:${pageContext.request.contextPath}<br>
5.获取请求方法:${pageContext.request.method}<br>
6.获取客户端ip地址:${pageContext.request.remoteHost}<br>
7.获取会话的id编号:${pageContext.session.id}<br>
</body>
</html>

 EL表达式其他隐含对象的使用

800612813b434f2ba37c22ba65d74475.png

web.xml中的配置 

<context-param>
  <param-name>username</param-name>
  <param-value>root</param-value>
</context-param>
<context-param>
  <param-name>url</param-name>
  <param-value>jdbc:mysql:///test</param-value>
</context-param>

09e2695e909c419aa04dfce37e5cb3af.png

 JSTL标签库

JSP Standard TagLibrary    JSP标准标签库

     是一个不断完善的开放源代码的JSP标签库。EL表达式主要是为了替换jsp中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个jsp页面变得更佳简洁

JSTL由五个不同功能的标签库组成

34afcea069244339bca79fa25de9e048.png

 IDEA中使用jstl标签库

idea使用jstl

<c:set />(使用很少)

作用:set标签可以往域中保存数据

<c:set scope="session" var="abc" value="abcValue"/>
保存之后:${sessionScope.abc}<br>

 <c:if/ >

  • if标签用来做if判断
  • test属性表示判断的条件(使用EL表达式输出)
     <c:if test="${12 == 12}">
         <h1>12等于12</h1>
     </c:if>
     <c:if test="${12 != 12}">
         <h1>12不等于12</h1>
     </c:if>

<c:choose><c:when><c:otherwise>

标签作用:多路判断。跟switch...case....default非常接近

b4da5011ccaa45cfa3c74728f185d23e.png

<c:forEach/>

作用:遍历输出使用 

    遍历1到10,输出

   <table border="1">
         <c:forEach begin="1" end="10" var="i">
             <tr>
                 <td>第${i}行</td>
             </tr>
         </c:forEach>
     </table>

   遍历Object数组

   <%        request.setAttribute("arr",newString[{"18610541354","18688886666","18699998888"});
    %>
    <c:forEach items="${requestScope.arr}" var="item">
        ${item}<br>
    </c:forEach>

  遍历Map集合

 <%
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        request.setAttribute("map",map);%>
    <c:forEach items="${requestScope.map}" var="entry">
        <h1>${entry.key}=${entry.value}</h1>
    </c:forEach>

Cookie饼干

  • Cookie翻译过来是饼干的意思
  • Cookie是服务器通知客户端保存键值对的一种技术
  • 客户端有了Cookie后,每次请求都发送给服务器
  • 每个Cookie的大小不能超过4kb
  • web程序是使用HTTP协议传输的,而HTTP协议是无状态的协议,对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。cookie的出现就是为了解决这个问题。
  • 第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。就相当于给客户端们颁发一个通行证,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

如何创建Cookie

528dd70b58d1468d8ac8cabc6c5eadeb.png

cookie的主要内容

    名字,值,过期时间,路径和域,路径与域一起构成cookie的作用范围。

生命周期:

    表示当前cookie的生命周期为浏览器会话期间,关闭浏览器则cookie消失。

Cookie什么时候产生 ?

  •         Cookie的使用一先要看需求。因为浏览器可以禁用Cookie,同时服务端也可以不Set-Cookie。
  •         客户端向服务器端发送一个请求的时,服务端向客户端发送一个Cookie然后浏览器将Cookie保存。
  •         Cookie有两种保存方式,一种是浏览器会将Cookie保存在内存中,还有一种是保存在客户端的硬盘中,之后每次HTTP请求浏览器都会将Cookie发送给服务器端。
    2d4e109313b44ff38e28830ce0fb4af0.png

session

什么叫web中的会话?

    用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

Session的定义

    在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息,一般存在服务器用来存放用户数据的类HashTable结构。

Session什么时候产生 ?

        当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
9f7b23054a844a79886d907eda88f748.png

服务器会向客户浏览器发送一个每个用户特有的会话编号sessionID,让他进入到cookie里。

2a4c5d915bda48379f194d30a743c388.png

服务器同时也把sessionID和对应的用户信息、用户操作记录在服务器上,这些记录就是session。再次访问时会带入会发送cookie给服务器,其中就包含sessionID

fa7b4a6f8c9b40f4a40c3d7cf994ab18.png

服务器从cookie里找到sessionID,再根据sessionID找到以前记录的用户信息就可以知道他之前操控些、访问过哪里。

5b428cbc047d486e933e945955758fd8.png

会话跟踪技术

    对同一个用户对服务器的连续的请求和接收响应的监视

    为什么需要会话跟踪技术?

    浏览器与服务器之间的通信是通过HTTP协议进行通信的,而HTTP协议是“无状态”的协议(早期主要用于web端获取内容,浏览了就结束,没有考虑交互的场景,所以服务器不会保留与用户交易的任何状态),客户端与服务器之间的联系是离散的、非连续的。多次请求,无法根据前后的请求来判断是否是同一个用户,面对越来越多的交互场景,会话跟踪技术应运而生

    种类

     从原理上分析,一次请求和响应主要参与的有服务器、客户端,以及通信的HTTP协议,多以分别从这三方面考虑,会话跟踪技术主要有以下四种:

  • Cookie
  • url重写
  • 隐藏表单域
  • Session

隐藏表单域

    隐藏表单域是利用 HTML 中的隐藏域,在网页表单内隐藏某些客户端的信息。在提交表单时,要将指定的名称和值自动包括在请求实体中,这些信息会随客户端的请求信息一起传送给服务器,服务器通过获取的这些信息来进行会话跟踪。
    这些识别信息是隐藏的,所以不会在客户端的浏览器页面上显示,但是,如果查看 HTML 的源文件,是可以看到这些隐藏字段的,这样很可能会导致用户资料的泄露。显然,这是使用隐藏域方式的一个缺陷
   

<form name="testform" action="/xxx">
	//隐藏域
	<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
	<input type="text">
</form>

URL重写

    客户程序在每个URL的尾部添加一些额外数据(以键值对的形式传递),这些数据标识当前的会话,服务器将这个标识符与它存储的用户相关数据关联起来。通常是添加 sessionID作为会话信息的标识

     http://172.23.22.58:8081/jjyhf;jsessionid=123456789

四种会话跟踪技术对比分析

Session的生命周期 ?

    一般情况下,服务器会在一定时间内(默认30分钟)保存这个 Session,过了时间限制,就会销毁这个Session。

    举个例子,你登录一个服务器,服务器返回给你一个sessionID,登录成功之后的半小时之内没有对该服务器进行任何HTTP请求,半小时后你进行一次HTTP请求,会提示你重新登录。

工作原理图:

1ecde0938f9b470db987c81fa0ee660e.png

若禁用了cookie那么session能不能使用?

    能使用。 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

 session和cookie的异同

相同点:

      两者都是一种记录用户状态的机制,都是为了减少客户端和服务器端之间的传输的冗余数据,提高两者之间的数据传输速率。

不同点:

  1.     Cookie可以存储在浏览器或者本地,Session只能存在服务器
  2.     session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象
  3.     Session比Cookie更具有安全性(Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击)
  4.     Session占用服务器性能,Session过多,增加服务器压力
  5.     单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie,Session是没有大小限制,只和服务器的内存大小有关。

session和cookie的结合使用

web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:

  •     储存在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。
  •     将session数据加密,然后储存在cookie中:这种专业术语叫做client side session。flask采用的就是这种方式,但是也可以替换成其他形式。

 Filter

      拦截请求,过滤响应

     在你的 web 工程下,有一个 admin 目录。这个 admin 目录下的所有资源(html 页面、jpg 图片、jsp 文件、等等)都必 须是用户登录之后才允许访问。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
      这是登录页面login.jsp
<form action="http://localhost:8099/jsp/login" method="get">
    用户名:<input type="text" name="username"> <br/>
    密 码:<input type="password" name="password"> <br/>
    <input type="submit">
</form>
</body>
</html>
public class LoginServlet extends HttpServlet {
    //登录跳转之后执行的操作
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码
        resp.setContentType("text/html;charset=UTF-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if ("admin".equals(username) && "123".equals(password)) {
            req.getSession().setAttribute("user", username);
            //将用户存入session之后在输出提示
            resp.getWriter().write("登录成功!!");
        } else {
            //重定向可以让地址保持不变,地址还是显示在servlet配置程序页面地址
            req.getRequestDispatcher("/error.jsp").forward(req,resp);;
        }
    }
}

public class LoginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    /**
     * 专门用于拦截请求,可以做权限检查
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession();
        Object user = session.getAttribute("user");
        if (user == null) { //如果没有获取到用户
            servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest, servletResponse);
            return;
        }else{
            //让程序继续往下访问用户的目标资源
            filterChain.doFilter(servletRequest,servletResponse);
        }
    }


    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
 <servlet>
        <servlet-name>Login</servlet-name>
        <servlet-class>alva.server.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

    <!--filter标签用于配置一个Filter过滤器-->
    <filter>
        <!--给filter起一个别名-->
        <filter-name>LoginFilter</filter-name>
        <!--配置全类名-->
        <filter-class>alva.server.LoginFilter</filter-class>
    </filter>
    <!--filter-mapping配置Filter过滤器的拦截路径-->
    <filter-mapping>
        <!--filter-name表示当前的拦截路径给哪个Filter使用-->
        <filter-name>LoginFilter</filter-name>
        <!--
            url-pattern配置拦截路径
                /   表示请求地址为:http://ip.port/工程路径/    映射到IDEA的web目录
                /admin/*    表示请求地址为:http://ip.port/工程路径/*
        -->
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>

现在进行测试,直接访问admin下面的hello页面

bb8f0acec8d8492c8a8ec174eb1a5ec1.png

会让你先登录,再测试登录之后再去访问

4e5ab4d7517248329b4f30b07f251992.png

 Filter的工作流程图

0c2ccb2705dd45cdbba62d8546eb8dfd.png

Filter过滤器的使用步骤:

  1. 编写一个类去实现Filter接口
  2. 实现过滤方法doFilter()
  3. 到web.xml中去配置Filter的拦截路径 

Filter生命周期

        1、构造器方法

        2、init 初始化方法
    
                    第 1,2 步,在 web 工程启动的时候执行(Filter 已经创建)

        3、doFilter 过滤方法
                    第 3 步,每次拦截到请求,就会执行(在xml中配置的,只要有该请求就进行拦截判断)

        4、destroy 销毁
                    第 4 步,停止 web 工程的时候,就会执行(停止 web 工程,也会销毁 Filter 过滤器)

FilterConfig类

     FilterConfig 类见名知义,它是 Filter 过滤器的配置文件类。 Tomcat 每次创建 Filter 的时候,也会同时创建一个 FilterConfig 类,这里包含了 Filter 配置文件的配置信息。

FilterConfig 类的作用是获取 filter 过滤器的配置内容

  • 获取 Filter 的名称 filter-name 的内容
  • 获取在 web.xml 中配置的 init-param 初始化参数
  • 获取 ServletContext 对象

web.xml中AdminFilter的初始化参数

<!--filter标签用于配置一个Filter过滤器-->
    <filter>
        <!--给filter起一个别名-->
        <filter-name>AdminFilter</filter-name>
        <!--配置全类名-->
        <filter-class>filter.AdminFilter</filter-class>
        <!--配置初始化参数-->
        <init-param>
            <param-name>username</param-name>
            <param-value>root</param-value>
        </init-param>
        <init-param>
            <param-name>url</param-name>
            <param-value>jdbc:mysql://localhost:13306/test</param-value>
        </init-param>
    </filter>
    <!--filter-mapping配置Filter过滤器的拦截路径-->
    <filter-mapping>
        <!--filter-name表示当前的拦截路径给哪个Filter使用-->
        <filter-name>AdminFilter</filter-name>
        <!--
            url-pattern配置拦截路径
                /   表示请求地址为:http://ip.port/工程路径/    映射到IDEA的web目录
                /admin/*    表示请求地址为:http://ip.port/工程路径/admin/*
        -->
        <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
@Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init(FilterConfig filterConfig)方法");
        //1、获取 Filter 的名称 filter-name 的内容
        System.out.println("filter-name :" + filterConfig.getFilterName());
        //2、获取在 wen.xml 中配置的 init-param 初始化参数
        System.out.println("初始化参数username的值是:" + filterConfig.getInitParameter("username"));
        System.out.println("初始化参数url的值是:" + filterConfig.getInitParameter("url"));
        //3、获取 ServletContext 对象
        System.out.println("ServletContext的值是:" + filterConfig.getServletContext());
    }

7785ce362e214e63b0f03c65fa00a52a.png

Filter的拦截路径 

精确匹配

<url-pattern>/target.jsp</url-pattern>         表示请求地址为:http://ip:port/工程路径/target.jsp

目录匹配

<url-pattern>/admin/*</url-pattern>        表示请求地址必须为:http://ip:port/工程路径/admin/*

后缀名匹配

<url-pattern>*.html</url-pattern>        表示请求地址必须以.html结尾才会拦截到

    注意:

    ① 后缀名可以自己设定,例如:<url-pattern>*.abc</url-pattern>

    ② 后缀名不要以斜杠  /   开头,若以斜杠开头会报错

            java.lang.IllegalArgumentException: 过滤器映射中的<url-pattern> [/*.abc] 无效

    ③ Filter过滤器值关心请求的地址受否匹配,不关心请求的资源是否存在

ThreadLocal

     它可以解决多线程的数据安全问题。

ThreadLocal 它可以给当前线程关联一个数据(可以是普通变量,可以是对象,也可以是数组,集合)

特点:

  •     ThreadLocal 可以为当前线程关联一个数据。(它可以像 Map 一样存取数据,key 为当前线程)
  •      每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数据,就需要使用多个 ThreadLocal 对象实例。
  •      每个 ThreadLocal 对象实例定义的时候,一般都是 static 类型
  •      ThreadLocal 中保存数据,在线程销毁后。会由 JVM 虚拟自动释放。

JSON&Ajax详解

JSON和Ajax

练习题

在jsp页面中输出九九乘法口诀表

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>a</title>
</head>
<body>
<h1>九九乘法表</h1>
<table>
    <%
        for (int i = 1; i <= 9; i++) { %>
    <%-- 外层循环遍历行 --%>
    <tr>
        <%-- 外层循环遍历单元格 --%>
        <% for (int j = 1; j <= i; j++) { %>
        <td><%= j + "x" + i + "=" + (i * j)%>
        </td>
        <% } %>
    </tr>
    <% }
    %>
</table>
</body>
</html>

jsp输出一个表格,里面有10个学生信息

创建student实体类

public class Student {
    private Integer id;
    private String name;
    private Integer age;
    private String phone;


    public Student() {
    }

    public Student(Integer id, String name, Integer age, String phone) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.phone = phone;
    }


    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", phone='" + phone + '\'' +
                '}';
    }
}

StudentSearchServlet程序

public class StudentSearchServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //获取请求的参数
        //发 sql 语句查询学生信息
        //使用for循环生成查询到的结果做模拟
        List<Student> students = new ArrayList<Student>();
        for (int i = 0; i < 10; i++) {
            int t = i + 1;
            students.add(new Student(t, "name" + t, 18 + t, "phone" + t));
        }
        //保存查询到的结果 到 request 域中
        req.setAttribute("studentList",students);
        //请求转发 到 showStudent.jsp 页面
        req.getRequestDispatcher("/a.jsp").forward(req,resp);

    }
}

web.xml

 <servlet>
        <servlet-name>StudentSearchServlet</servlet-name>
        <servlet-class>alva.servlet.StudentSearchServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>StudentSearchServlet</servlet-name>
        <url-pattern>/student</url-pattern>
    </servlet-mapping>

先运行b.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>test2</title>
</head>
<body>
   <a href="http://localhost:8099/server/student">搜索</a>
</body>
</html>

a.jsp展示表格

<%@ page import="alva.pojo.Student" %>
<%@ page import="java.util.List" %>
<%--
  Created by IntelliJ IDEA.
  User: ASUS9
  Date: 2022/11/24
  Time: 18:48
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>学生信息</title>
    <style type="text/css">

        table{
            border: 1px blue solid;
            width: 600px;
            border-collapse: collapse;
        }
        td,tr,th{
            border: 1px blue solid;
        }

    </style>
</head>
<body>

<%
    List<Student> students = (List<Student>) request.getAttribute("studentList");
%>
<table>

    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>年龄</th>
        <th>电话</th>
        <th>操作</th>
    </tr>

    <%for (Student student : students) {%>

    <tr align="center">
        <td><%=student.getId()%></td>
        <td><%=student.getName()%></td>
        <td><%=student.getAge()%></td>
        <td><%=student.getPhone()%></td>
        <td>
            <a href="">删除</a>
            <a href="">修改</a>
        </td>
    </tr>

    <% } %>
</table>

</body>
</html>

遍历List集合---list中存放Student类,有属性:编号,用户名,密码,年龄,电话信息

student类

public class Student{
   //4.编号,用户名,密码,年龄,电话信息
 private Integer id;
 private String username;
 private String password;
 private Integer age;
 private String phone;
}
<%--4.遍历List集合---list中存放Student类,有属性:编号,用户名,密码,年龄,电话信息--%>
<%
  List<Student> studentList = new ArrayList<Student>();
   for(inti=1;i<=10;i++){
     studentList.add(new Student(i,"username"+i,"pass"+i,18+i,"phone"+i));
}
   request.setAttribute("stus",studentList);
%>
    <table>
      <tr>
        <th>编号</th>
        <th>用户名</th>
        <th>密码</th>
        <th>年龄</th>
        <th>电话</th>
        <th>操作</th>
      </tr>
<%--items表示遍历的集合var表示遍历到的数据begin表示遍历的开始索引值end表示结束的索引值step属性表示遍历的步长值varStatus属性表示当前遍历到的数据的状态for(inti=1;i<10;i+=2)--%>
<c:forEach  begin="2" end="7" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
     <tr>
       <td>${stu.id}</td>
       <td>${stu.username}</td>
       <td>${stu.password}</td>
       <td>${stu.age}</td>
       <td>${stu.phone}</td>
       <td>${status.step}</td>
     </tr>
</c:forEach>
    </table>

    编写JSP程序,在当前web应用目录下创建文件夹abc,并在该文件夹下创建文本文件”cba.txt”

<%@ page language="java" contentType="text/html; charset=gb2312"%> 
<%@ page import="java.io.*"%> 
<html>
	<head>
		<title>创建文件和文件夹</title>
	</head>	
	<body>
<%
	String path = request.getRealPath("/");
	String abc_path = path+"abc";
	File fp1 = new File(abc_path);
	fp1.mkdir();
	File fp2 = new File(abc_path,"cba.txt");
	fp2.createNewFile();
%>	
		<center>
			创建了文件夹abc:<br>			
			并在该文件夹下创建了文件cba.txt<br>	
		</center>
	</body>
</html>

习题(错题分享)

选择

1.  web是动态的,而非静态

2.  JSP中的不是隐式注释为(  A  )

  • A.<!—注释内容-->
  • B.<%--注释内容--%>      
  • C. // 注释内容  
  • D. /* 注释内容 */
  •      Html注释,该注释可以通过查看源代码看到

3.  在inc.jsp中包含数行代码与一张图片,现在要创建一个home.jsp,每次浏览home.jsp时都能够以最快的速度显示inc.jsp中的所有内容以及home.jsp自身要显示的内容,应该在home.jsp中使用的语句是(  c    )

  • A.<% @ include page = “inc.jsp”%>
  • B.<jsp:forward page = “inc.jsp”/>
  • C.<% @ include file = “inc.jsp”%>
  • D.<jsp:include file = “inc.jsp”flush = “false”>

 Jsp:include 里面的是page,@include里面的才是file

4.  对于预定义<%!预定义%>的说法错误的是(  D    )

  • A.在预定义中声明的变量将在JSP页面初始化时初始化
  • B.一次可声明多个变量和方法,只要以“;”结尾就行   
  • C.一个声明仅在一个页面中有效
  • D.声明的变量将作为局部变量

5.  在JSP中,只有一行代码:<%=’A’+’B’%>,运行将输出(  A    )

  • A. 131
  • B.A+B
  • C.错误信息,因为表达式是错误的
  • D.AB
  •    单引号是ASCII   双引号是字符

  • 6.  “java”是当前唯一可用的JSP语言

7.  下面哪一个不是JSP本身已加载的基本类?(      )

  • A.java.lang.*    
  • B.javax.servlet.*
  • C.java.io.*
  • D.javax.servlet.jsp.*

8.  对该段代码描述错误的有<% int i = Integer. parseInt(requrst.getParemeter(“value”)) %(  A

  • A.不会有错
  • B.当value与int 类型不匹配时会报错
  • C.为了安全起见应该将该段代码放在try{}和catch(){}之间
  • D.当value=""时会报错

9.   以下的代码执行过程描述正确的是(C

out.println("<script>");
out.println("alert('good')");
out.println("</script>");
System.out.println("the servlet info");
out.close();
  • A.执行到2的时候会在客户端页面弹出一个对话框,当客户响应过后继续执行下面的代码
  • B.执行到2的时候会在客户端页面弹出一个对话框,但是会继续执行下面的代码
  • C.执行完上面的所有代码后,客户端才会得到服务器的响应,然后才弹出对话框
  • D.以上都不对

10.   WEB应用中,常用的会话跟踪方法不包括(  C    )

  • A.隐藏表单域
  • B.Cookie  
  • C.有状态HTTP协议
  • D.URL重写

11.  pageContext对象创建和初始化都是由容器来完成

12.  隐藏域在Cookie被禁用或者根本不支持的情况下依旧能够工作

13.  servlet 的生命周期又一系列事件组成,把这些事件按照先后顺序排序,以下正确的是(C

  • A.加载类,初始化,实例化,请求处理,销毁
  • B.加载类,实例化,请求处理,初始化,销毁
  • C.加载类,实例化,初始化,请求处理,销毁
  • D.实例化,加载类,初始化,请求处理,销毁

14. 下面哪一项对Servlet描述错误?( C )  

  • A:Servlet是一个特殊的Java类,它必须直接或间接实现Servlet接口
  • B:Servlet接口定义了Servlet的生命周期方法
  • C:当多个客户请求一个Servlet时,服务器为每一个客户启动一个进程
  • D:Servlet客户线程调用service方法响应客户的请求

   Servlet为每个用户启动的是线程,而不是进程

15.  下述选项中不属于JDBC基本功能的是(   B   )

  • A.处理查询结果
  • B.数据库维护管理
  • C.提交SQL语句
  • D.与数据库建立连接

16.  DriverManager类的getConnection(String url,String user,String password)方法中,参数url的格式为jdbc:<子协议>:<子名称>,下列哪个url是不正确的?(B

  • A:"jdbc:mysql://localhost:3306/数据库名" 
  • B:"jdbc:odbc:数据源"
  • C:"jdbc:oracle:thin@host:端口号:数据库名" 
  • D:"jdbc:sqlserver://172.0.0.1:1443;DatabaseName=数据库名"

URL的通常格式为:jdbc:(哪种数据库)://数据库地址:数据库端口号/数据库名字?编码格式

17. 一个taglib指令必须有那些属性(  C  )

  • A.value prefix
  • B.uri loaction
  • C.uri prefix
  • D.uri value

填空

1.用java实现的动态网页,要在tomcat下发布可以直接发布在默认的(_ webapps/ROOT_)目录下。但是我们一般都愿意发布在自己的目录里,这样的目录我们是需要在tomcat里配置的,配置虚拟目录的文件夹是(__conf__)。在这个目录里的(_server.xml_)文里可以配置,在tomcat5.0以后一般都配置在单个的.xml里。这样的.xml里指定虚拟目录的名字的属性是(_path_)

2. 设置错误处理页面:_<%@ page isErrorPage= “true” %>_ 如果当前JSP页面出现异常时需要转到一个异常页,需要设置page 指令_errorPage_属性

3.  当用户请求jsp页面时,JSP引擎就会执行该页面的字节码文件响应客户的请求,执行字节码文件的结果是(_发送一个HTML页面到客户端_)

4.  web 容器处理JSP 请求需要经历三个阶段(_翻译_),(_编译_),(_执行_)

5.  session对象的(_session.setMaxInactiveInterval(30)_)方法用于设置会话的超时时间

6.  释放session对象时,使用session对象的( _invalidate()_)方法

7.  session对象getId方法的作用是(__得客户端在服务器唯一的标识)

8.  理论上,GET是(_用于获取服务器信息并将其作为响应返回给客户端_),POST是 (__用于客户端把数据传送到服务器_)。

9.  在JSP页面中,(__response_)等效于HttpServletResponse 

10. 一个Bean由三部分组成:(_实现java.io.serializable接口_)、(_提供无参数的构造方法_)、(_提供getter()和setter()方法访问它的属性_)

11. 在JSP中使用JavaBean的标签是(_<jsp:useBean class=BeanName id=Bean实例>_),其中id的用途是(_实例化一个Bean对象 __) 。

12.  Servlet的生命周期分三个时期:(_装载Servlet_)(_创建一个Servlet实例_)(__销毁_)

13.  JSP开发网站的两种模式分为(_jsp+javabean_)和(_jsp+javabean+servlet_)。

简答

1.  在jsp 页面输出 hello world 至少三种方式。

  1.        <%=hello world %>
  2.        out.println("hello world ")
  3.        hello world

2.  JSP中动态include与静态include的区别?

  •       动态包含是在实际用到被包含页面的时候才去加载被包含的页面,包含和被包含页面被编译为2个servlet文件,会检查所含文件中的变化。
  •        静态包含是直接把包含的页面信息添加到自己页面,只被编译成一个jsp页面,被包含的页面被编译到包含它的页面中,不会检查所含文件的变化

3. JSPservlet的异同  

相同点:
(1)两者都是基于Java的技术,所以都继承了Java的所有特性(跨平台、多线程等 ),都可以使用Java强大的API。
(2)两者工作方式相似:JSP代码先被JSP容器转换为Servlet代码再编译为类。
(3)两者在J2EE体系结构中的工作层次相同,都负责与客户端的连接。
不同点:

  • (1)编程方式不同。Servlet是一些运行于Web服务器端的Java小程序;而JSP是脚本,编写起来更简单容易。
  • (2)应用目的不同。Servlet主要用于从客户端接收请求信息,而JSP主要负责将服务器端信息传送 到客户端

4. 数据连接池的工作机制

     J2EE服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量有配置参数决定。当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接

;