JSP+Servlet+JDBC的世界等你来

JSP+Servlet+JDBC

1.Web相关概念

1.1软件架构

  • B/S:浏览器端/服务器端
  • C/S:客服端到服务器端

1.2资源分类

  • 静态资源:所有用户访问结果都一样,成为静态资源,静态资源可以直接被浏览器解析

    • 如HTML,CSS
  • 动态资源:每个用户访问相同的资源,得到结果可能不同,称为动态资源。动态资源被访问后,需要先转换为静态资源,再返回给浏览器。

    • 如JSP+Servlet,php

1.3网络通信三要素

IP:电子设备在网络中唯一标识

端口:应用程序在计算机中唯一标识。0-65536

传输协议:规定了数据的传输规则。

1.TCP:可靠,三次握手,速度慢,数据大小无限制

2.UDP:不可靠,不建立连接,传输速度快,数据大小有限制

1.4服务器

  • 服务器:安装了服务器软件的计算机

  • 服务器软件:接受用户请求,处理请求,做出响应的软件

  • web服务器软件:接受用户请求,处理请求,做出响应的软件

    • 它里面可以部署web项目,让用户通过浏览器来访问这些项目

    • 动态资源必须依赖web服务器才能运行,所以也被称为web容器

  • 常见的Java相关的web服务器软件

    • Tomcat: Apache基金组织,中小型的JavaEE服务器,仅支持少量JavaEE规范,开源免费,性能优异,支持集群,所以深受广大企业喜爱。
    • webLogic:oracle公司,大型的JavaEE服务器,支持所有JavaEE规范,收费
    • webSphere:IBM公司,大型的JavaEE服务器,支持所有JavaEE规范,收费
    • JBOSS:JBoss公司,大型的JavaEE服务器,支持所有JavaEE规范,收费

2.Tomcat

2.1下载

2.2安装

解压即可使用

建议:安装目录不要有中文和空格

2.3目录结构

2.4卸载

删除文件夹即可

2.5启动

bin/startup.bat

启动报错

  • 解决方案:logs----catalina.当天日期.log—在日志找错误信息----百度

启动窗口闪退

  • 解决方案:JAVA_HOME配置有问题,正确配置后,就可以修复此问题

重复启动,端口号占用(日志)

  • 解决方案1:干掉端口号:cmd—netstat (-ano)–看最右PID后在任务管理器详细信息找到结束任务
  • 解决方案2:修改Tomcat端口号,(config—server.xml—修改8080)

2.6关闭

  • 正常关闭

    • bin/shutdown.bat
    • 启动窗口:ctrl+c
  • 强制关闭

    • 右上角点x

2.7项目部署

方式1:直接将项目复制到webapps下

  • /MyWeb项目访问路径,其实他是一个虚拟路径,没有配置前,默认是实际路径

方式2:将项目打包成war包复制到webapps下

  • 服务器会为我们自动的部署项目,删除项目只需删除war包,对应的项目也会自动被删除

方式3:通过配置server.xml

1.在配置文件中找到Host标签

2.在Host标签中加入配置

<Context docBase="项目路径" path="虚拟路径" />
  • Context:自闭和标签
  • docBase:项目存放路径
  • path:访问的虚拟路径

缺点:server.xml是针对服务器的配置文件,一般我们不会修改这个文件,因为稍有不慎,就会导致服务器崩溃

方式4:在conf/Catalina/localhost/文件夹中创建 虚拟路径.xml

  • 在该xml文件中添加标签
<Context docBase="D:\MyLove" path="/baidu" />

该方式的好处:1.不用修改配置文件,2支持热部署

3.Servlet

3.1概述

​ 运行在服务端的java小程序

  • Servlet是一个接口,定义了Java类可以被Tomcat识别的规则
  • 针对Servlet的开发就是实现Servlet接口,重写里面的方法即可

3.2快速入门

步骤:

1.创建JavaEE项目

2.定义一个类,实现Servlet接口

3.实现接口中的抽象方法

4.配置Servlet

创建Servlet无法实现接口解决方式:

打开web.xml配置如下代码

<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>org.wdit.servlet.FirstServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>demo1</servlet-name>
    <url-pattern>/demo1</url-pattern>
</servlet-mapping>

或者导入tomcat下的servlet-api.jar

执行原理:

1.服务器接收到浏览器的请求后,会解析URL路径,获取访问Servlet的资源路径(/demo)

2.查找web.xml文件中是否有对应的<url-pattern>

3.如果有,就会找到对应的<Servlet-class>,拿到对应的Servlet的全限定类名

4.tomcat将对应的字节码文件加载到内存中,并创建该类对象

5.调用service()方法

3.3 Servlet方法和生命周期

1.生命周期:

  • 被创建:执行init方法 ,只执行一次

    • init()方法加载时间可以被改变:通过web.xml配置
  • 提供服务:执行service()方法,执行多次

  • 被销毁:服务器正常关闭,执行destroy,只执行一次

注意事项:Servlet是单例模式:

​ 多个用户访问可能存在线程安全问题,尽量不要使用Servlet中使用成员变量(在堆内存中),即使定义了成员变量,也不要有修改值的操作。

3.4注解配置

步骤:

1.创建JavaEE项目,选择3.0之后的版本,可以不创建web.xml

2.定义一个类,实现Servlet接口

3.重写方法

4.在类上使用注解进行配置

注意

1.Web-inf下的资源被浏览器访问不到

2.工作空间的项目和tomcat部署的web项目(CATALINA_BASE\work)并不是一个项目

3.5Servlet继承体系结构

Servlet接口

​ |实现

GenericServlet 抽象类

​ |继承

HttpServlet抽象类

  • GenericServlet 抽象类:它将Servlet接口中的其他方法都做了实现,只留下了Service()方法作为抽象方法
  • HttpServlet抽象类:该抽象类是对Http协议的一种封装,可以简化操作

3.6HttpServlet

步骤:

1.定义类,继承HttpServlet

2.重写doPost()/doGet()

3.7 urlPatterns()属性

1.一个Servlet可以配置多个访问路径

2.路径定义规则:

  • 路径匹配:/xxx

  • 目录结构匹配:/xxx/xxx

  • 扩展名匹配:*.xxx

  • package org.wdit.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;
    
    /*HttpServlet*/
    //@WebServlet("/demo2")
    @WebServlet(urlPatterns = {"/a","/aa","/aaa"})
    public class ServletDemo2  extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("deGet.......");
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("doPost..........");
        }
    }
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
       <form action="demo2" method="post">
            <input type="text" name="usename">
           <input type="password" name="password">
           <input type="submit"  value="登录" >
    
       </form>
    </body>
    </html>
    

4.Http协议

4.1概念

Http:Hyper Text Transfer Protocol-超文本传输协议

4.2特点

1.基于TCP/IP的高级协议:安全的

2.默认端口号:80

3.基于请求和响应模型:一次请求对应一次响应

图示:

4.3请求消息-数据格式

GET / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BAIDUID=7ED3E8EA26D338BCDA80C3EC13DC3C83:FG=1; BIDUPSID=7ED3E8EA26D338BCF730592B5E7B5F74; PSTM=1614497992; BD_HOME=1; H_PS_PSSID=33514_33355_33257_33344_33595_33570_26350_33568; BD_UPN=13314752; BA_HECTOR=0g8k248184040080q91g3mie40r
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

4.4请求行

格式:请求方式 /请求的URL/请求的协议/版本号

请求方式:

  • GET

  • 请求参数在请求行中,URL后

  • 请求的URL长度是有限制的

  • 不安全的

  • POST

    • 请求参数在请求体中
    • 请求的URL长度无限制
    • 相对安全

4.5请求头

请求头内容就是浏览器告诉服务器它自身的一些信息。

  • 常见的请求头

    • Host:被请求的主机
    • User-Agent:浏览器告诉服务器,当前浏览器的版本信息
    • Accept:浏览器告诉服务器自己支持的格式
    • Referer:告诉服务器,当前请求从哪里来

4.6请求空行

4.7请求体

格式:参数:对应的值

POST/ HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: BAIDUID=7ED3E8EA26D338BCDA80C3EC13DC3C83:FG=1; BIDUPSID=7ED3E8EA26D338BCF730592B5E7B5F74; PSTM=1614497992; BD_HOME=1; H_PS_PSSID=33514_33355_33257_33344_33595_33570_26350_33568; BD_UPN=13314752; BA_HECTOR=0g8k248184040080q91g3mie40r
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
//请求空行

usename=aaa & password=aaa

5.Request对象

5.1 request和 response对象的原理

通过原理图,我们得出:

1.request和response对象是由服务器创建,我们直接使用即可

2.request对象用来获取请求消息,response对象设置响应消息

ServletRequest----接口

​ |(被继承)

HttpServletRequest----接口

​ |(被实现)

org.apache.catalina.connector.RequestFacade-----------由tomcat在该类中做的具体实现

5.3获取请求消息数据

5.3.1获取请求行数据

我们根据请求行的格式来分析需要的方法

Get  /demo2/demo2 HTTP/1.1
  • 获取请求方法:GET

    • String getMethod()
  • 获取虚拟目录:/demo2

    • String getContextPath()
  • 获取资源路径:/a/(/aa)/(/demo2)

    • String getServletPath()
  • 获取get方式请求参数:?usename=aaa&password=aaa

    • String getQueryString()
  • 获取请求URI:/demo2/demo2

    • String getRequestURI():/demo2/demo2
    • String getRequestURL():http://localhost:8080/demo2/demo2
  • 获取协议及版本号:HTTP/1.1

    • String getProtocol()

    获取客户机的IP地址

    • String getRemoteAddr()
    package org.wdit.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;
    
    /**/
    @WebServlet("/demo3")
    public class ServletDemo3  extends HttpServlet {
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("post........");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //1.获取请求方式
            String method = req.getMethod();
            System.out.println(method);
            //2.获取虚拟目录
            String contextPath = req.getContextPath();
            System.out.println(contextPath);
            //3.获取Servlet路径
            String servletPath = req.getServletPath();
            System.out.println(servletPath);
            //4.获取get方式请求参数
            String queryString = req.getQueryString();
            System.out.println(queryString);
            //5.获取请求URI
            String requestURI = req.getRequestURI();
            StringBuffer requestURL = req.getRequestURL();
            System.out.println(requestURI);
            System.out.println(requestURL);
            //6.获取协议及版本号
            String protocol = req.getProtocol();
            System.out.println(protocol);
            //7.获取客户机的IP
            String remoteAddr = req.getRemoteAddr();
            System.out.println(remoteAddr);
        }
    }
    
5.3.2获取请求头
  • String getHeader(String name):通过请求头的名称获取请求头的值
  • **Enumeration getHeaderNames()😗*获取所有请求头名称
    • Enumeration相当于迭代器
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.util.Enumeration;

/**/
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            //根据头对应的名称拿对应的值
            String value = req.getHeader(name);
            System.out.println(name+"----"+value);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

防盗链案例演示

package org.wdit.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.util.Enumeration;

/*防盗链演示*/
@WebServlet("/demo6")
public class ServletDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      //1.获取referer
        String referer = req.getHeader("referer");
        System.out.println(referer);
          if(referer.contains("http://localhost:8080/")){
              System.out.println("开始播放。。。。。。");
          }else{
              System.out.println("滚");
          }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post..........");
    }
}
5.3.3获取请求体
  • 请求体:只有POST方式有请求体
  • 步骤:
    • 获取流对象
    • 从流中获取数据
package org.wdit.servlet;

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

/*获取请求体数据*/
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*//1.获取流
        BufferedReader reader = req.getReader();
        //2.读数据
        String line=null;
        while((line=reader.readLine())!=null){
            System.out.println(line);

        }*/


        //获取流
        ServletInputStream inputStream = req.getInputStream();
        byte[]bytes=new byte[1024];
        int len=0;
        while((len=inputStream.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
            len=inputStream.read(bytes);
        }
5.3.4其他方法

这些方法是在前面基础方法上衍生出来的一些通用方法,更方便使用

1.获取请求参数对象(GET/POST)都能用

  • **String getParameter(String name)**根据参数名称获取参数值

  • **String[] getParameterValues(String name)**根据参数名获取参数值的数组

  • **Enumeration getParameterNames()😗*获取所有请求的参数名称

  • Map<String,String[]> getParameterMap():获取所有参数的Map集合

  • 解决中文乱码问题

    • request.setCharacterEncoding(“utf-8”)
package org.wdit.servlet;

import jdk.dynalink.linker.GuardingTypeConverterFactory;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


@WebServlet("/demo8")
public class ServletDemo8 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        //根据参数名获取参数值
        String usename = req.getParameter("usename");
        String password = req.getParameter("password");
        System.out.println(usename+"----"+password);

    //获取复选框的参数值
        String[] hobbies = req.getParameterValues("hobby");
        for(String hobby:hobbies){
            System.out.println(hobby);
        }


        //获取请求中所有的参数名
        Enumeration<String> parameterNames = req.getParameterNames();
        while(parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String value = req.getParameter(name);
            System.out.println(name+":  "+value);
        }


        //返回所有参数的Map集合
        Map<String, String[]> parameterMap1 = req.getParameterMap();
        //遍历Map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> keys = parameterMap.keySet();
        Iterator<String> iterator = keys.iterator();
        while(iterator.hasNext()){
            String s = (String)iterator.next();
            String[] values = parameterMap.get(s);
            for(String value:values){
                System.out.println(s+"----"+value);
            }

        }
    }}

2.请求转发

  • 概述:一种在服务器内部资源跳转的方式

  • 步骤:

    1.通过request对象获取请求转发器对象

    • RequestDispatcher getRequestDispatcher(String path)

    2.使用转发器对象进行转发

    • forward(ServletRequest request,ServletResponse response)
    package org.wdit.servlet;
    
    import javax.servlet.RequestDispatcher;
    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.util.Enumeration;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Set;
    
    
    @WebServlet("/demo9")
    public class ServletDemo9 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           this.doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            req.setCharacterEncoding("utf-8");
            System.out.println("demo9被访问了");
            //转发
    req.getRequestDispatcher("/demo10").forward(req,resp);
    
    
    
        }}
    
  • 特点:

​ 1.浏览器地址栏路径不发生变化

​ 2.只能转发当前服务器内部资源

​ 3.转发它是一次请求:无论内部转发多少次,调用几个Servlet,它都是一次请求

3.数据共享

  • 概述:多个Servlet间协作 数据的共享,在学习共享之前,我们需要学习:域对象

  • 域对象:一个有作用范围的对象,在作用范围之内可以共享数据

  • Request域:代表一次请求的范围。它的作用范围刚好就是请求转发的范围,所以request域对象一般用于多个资源共享数据。一次请求多个资源

    ​ 1. **void setAttribute(String name,Object obj)😗*存储数据

         2. **Object getAttribute(String name)**:获取数据
            3. **void remove Attribute(String  name)**:删除数据
    

设置请求参数

package org.wdit.servlet;

import javax.servlet.RequestDispatcher;
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.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;


@WebServlet("/demo9")
public class ServletDemo9 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        System.out.println("demo9被访问了");
        //转发
req.getRequestDispatcher("/demo10").forward(req,resp);
req.setAttribute("info","我真厉害");



    }}

收到参数

package org.wdit.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;


@WebServlet("/demo10")
public class ServletDemo10 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        System.out.println("demo10被访问了");
        Object info = req.getAttribute("info");
        System.out.println(info);


    }}

4.ServletContext对象

  • ServletContext getServletContext()
  • 后面细讲 很重要

5.4用户登录

需求:

​ 1.编写login.html登陆页面

2.连接数据库,判断页面传来的用户信息是否在数据库中存在

3.根据查询信息

  • ​ 存在:登陆成功----转发到SuccessServlet并在页面输出欢迎+用户名+登录
  • 不存在:登陆失败—转发到ErroServlet并在页面输出:用户名或密码错误

分析:

1.新建Module

  • 添加web依赖
  • 配置tomcat-将该项目部署到tomcat-中文乱码,虚拟路径

2.导包:mysql驱动包,Druid连接,JDBCTemplate

3.添加配置文件:druid.properties

4.创建包结构,添加工具类:JDBCUtils(org.wdit.utils)

5.5BeanUtils使用要求

1.类必须是public

2.类必须提供无参构造

3.成员变量必须被private修饰

4.提供公共的get/set方法

6.Http响应消息

1.请求消息:客户端发送给服务端数据

  • 请求行
  • 请求头
  • 请求空行
  • 请求体:
    • Post:有请求体
    • Get:以参数的方式,在请求行中

2.响应消息:服务器回应给客户端消息

  • 响应行
  • 响应头
  • 响应空行
  • 响应体

6.1响应行

1.组成

协议/版本 响应状态码 响应码描述

2.状态码

  • 分类:
  1. 1xx- 服务端接收客户端信息,但没有接收完成,等待一段时间后,发1xx状态码,询问客户端是否继续发送消息
  2. 2xx-成功 代表:200
  3. 3xx-重定向,资源跳转的方式,代表码:302-重定向 304-访问缓存
  4. 4xx:客户端错误,比如访问路径有问题,没有对应资源:404
  5. 5xx:服务端错误,比如服务器代码出现异常:500

6.2响应头

1.组成

​ 头名称:值

2.常见响应头

  • content-type :服务器告诉客户端本次响应体数据格式即编码 格式
  • content-dispotion:服务器告诉客户端以什么方式打开响应体数据,如果没有设置,则使用默认值
    • in-line:默认值,在当前页面打开
    • attachment;filename=xxx:以附件按形式打开响应体。及文件下载filename是文件下载的默认名字

6.3验证码

**本质:**就是一张图片

**目的:**提高安全性,防止恶意注册,恶意登录

**方式:**随机产生

7.Response对象

7.1概述

Response对象是用来设置响应消息的

7.2主要方法

1.设置响应行

  • 设置响应状态码:setStatus(int SC)–SC:状态码

2.设置响应头

  • setHeader(string name,String value)
package org.wdit.response;

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;

/*重定向*/
@WebServlet("/resp1")
public class responseDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("responseDemo被访问");
//       //设置状态码
//        resp.setStatus(302);
//        //设置响应头
//        resp.setHeader("location","/demo2/resp2");
        String contextPath=req.getContextPath();
        resp.sendRedirect(contextPath+"/resp2");
        //简化书写
       // resp.sendRedirect("/demo2/resp2");
    }
}

3.设置响应体

  • 步骤:

    • 1.获取输出流

      • 字节输出流:ServletOutputStream getOutputStream()
      • 字符输出流:printWriter getWriter()
    • 2.使用输出流将数据输出客户端浏览器

      public class responseDemo3 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              this.doPost(req, resp);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //设置头信息
              //resp.setHeader("content-type","text/html;charset=utf-8");
             resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().write("哈哈");
      
      
      
      
             /* //获取输出流
              PrintWriter printWriter= resp.getWriter();
              printWriter.write("<h1>Hello response</h1>");
              printWriter.write("你好,response");//乱码*/
      
              /*
              * 分析:中文乱码
              * QQ浏览器:默认GBK
              * 输出流通过Tomcat获取:编码集理论上应该是ISO-8859-1
              *
              * */
              //解决中文乱码
              /*//1.获取流之前设置编码集
              resp.setCharacterEncoding("GBK");
      */
      
          }
      }
      

输出字节流

public class responseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

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

       //设置编码
        resp.setContentType("text/html;charset=utf-8");
        //获取流
       resp.getOutputStream().write("你好".getBytes());


    }
}

7.3重定向

图解:

步骤:

1.设置状态码:302

2.设置响应头:Location

面试题: 转发forward 和 重定向redirect 区别:

  • 转发:

    1.一次操作,一次请求

​ 2.服务器内部资源间操作

​ 3.地址栏路径url没变

​ 4.只能访问当前服务器资源

​ 5.可以使用request对象共享数据

  • 重定向:

    1.一次操作,多次请求

​ 2.客户端和服务器间的操作

​ 3.地址栏路径url改变

​ 4.可以访问外部服务器资源

​ 5.不可以使用request对象共享数据,因为重定向是两次请求

  • 路径书写:

    • 相对路径:找到当前资源 和 目标资源之间的相对位置关系

      • ./开头
      • ../表示上一级目录
    • 绝对路径

      • /开头:因为当前项目中localhost:8080/虚拟目录都是统一格式,所以我们可以省略为/

      • 判断标准“

        1.浏览器使用,需要加虚拟目录

        2.服务器使用不需要加虚拟目录

8.ServletContext对象

8.1概述

ServletContext对象代表整个Web应用

8.2获取对象

1.通过Request对象获取

  • request.getServletContext()

2.通过HttpServlet获取

  • this.getServletContext()

8.3功能

1.获取MIME类型

  • MIME类型:在互联网通信过程中定义的一种文件数据类型
  • 格式:大数据类型/小数据类型 比如:text/ html
  • 获取:String getMimeType(String file):通过文件名(包括扩展名)获取MIME的值
    • 扩展名对应的MIME值可以通过tomcat安装路径—conf—web.xml查看

2.域对象:共享数据

  • void seSetAttribute(String name ,Object obj):存储数据
  • **Object getAttribute(String name)😗*通过参数名获取参数值
  • **void removeAttribute(String name)😗*通过移除参数名删除数据

3.作用域

  • 最大范围 :所有用户的所有连接

两次请求案例

package org.wdit.ServletContext;

import javax.servlet.ServletContext;
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;

@WebServlet("/context3")
public class ServletContextDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
      servletContext.setAttribute("info","AEd2 ");
    }
}
package org.wdit.ServletContext;

import javax.servlet.ServletContext;
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;

@WebServlet("/context4")
public class ServletContextDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        String info = (String) servletContext.getAttribute("info");
        System.out.println(info);
    }
}

8.4文件下载

需求:

​ 1.在html文件中写一个超链接

​ 2.点击超链接弹出下载提示框

​ 如果超链接 href指向图片路径,因为浏览器的解析器可以解析图片,所以会直接显示出来,如果指向的是视频,因为浏览器无法解析,就会默认弹出下载框

​ 3.下载文件

分析:

​ 需要设置响应头设置资源打开方式,否则图片无法通过超链接进行下载

  • content-disposition:attachment;filename=xxx

步骤:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
   <form action="/demo2/demo7" method="post">
     请输入用户名: <input type="text" name="usename"><br>
      请输入密码: <input type="password" name="password"><br>
       <input type="submit"  value="登录" >

   </form>
<a href="/demo2/image/hx.jpg ">诗和远方</a>
<a href="/demo2/video/h.mp4 ">视频</a>
</body>
</html>
package org.wdit.ServletContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

/*
* 文件下载演示案例*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   //获取文件名
        String fileName=req.getParameter("fileName");
        //获取文件真实路径
        ServletContext servletContext = this.getServletContext();
        String realPath = servletContext.getRealPath("/image/" + fileName);

        //设置响应头
        //设置MIME值
        String mimeType = servletContext.getMimeType(fileName);
        resp.setHeader("content-type",mimeType);

        //设置打开方式
        resp.setHeader("content-disposition","attachment;filename="+fileName);


        //获取输入输出流
        FileInputStream fis=new FileInputStream(realPath);
        ServletOutputStream outputStream = resp.getOutputStream();
        byte[]bytes=new byte[1024];
        int len=0;
        while((len=fis.read(bytes))!=-1){
            outputStream.write(bytes,0,len);
        }

        //释放资源
        fis.close();
    }
}

9.会话技术

概述:

​ 一次会话中包含多次请求和响应,并且在会话范围内可以共享数据

功能:

​ 共享数据

分类:

​ 1.客户端会话技术:Cookie

​ 2.服务器端会话技术:Session

9.1Cookie

概述:

客户端会话技术,将数据保存在客户端

步骤:

1.创建Cookie对象

  • new Cookie(String name,String value);

​ 2.发送Cookie对象

  • response.addCookie(String cookieName )

3.获取Cookie对象

  • Cookie[] request.getCookies()

注意事项:

1.一次可以发送多个Cookie:创建多个Cookie对象,多次调用addCookie()

2.Cookie在浏览器中保存多长时间

  • 默认情况下:浏览器关闭,Cookie数据被销毁
  • 持久化存储:
    • setMaxAge(int second):
    • second:正数,将Cookie数据写入到磁盘文件中,持久化存储,second具体数值,表示文件存活的时长。以秒为单位
    • 负数,默认值
    • 0,删除Cookie信息,因为服务器无法直接操作用户电脑。

3.Tomcat 8之前,不能直接存储数据,8版本以后可以直接存储中文,但是特殊字符依然不能存储,需要使用URL编码和解码 来存储和获取数据

4.Cookie的获取范围:

1.相同服务器多个web项目

  • 默认情况:一个Tomcat服务器中的多个Web项目是不共享Cookie数据的

  • 我们可以通过方法设置:setPath("/"),这样Cookie就可以共享了

    2.不同服务器

  • 通过setDomain()方法设置相同的一级域名,这些不同服务器之间的Cookie就可以共享了

  • tieba.baidu.com:baidu.com就是一级域名

特点:

1.存储少量,内容不敏感的数据

​ 2.大小有限制:单个Cookie大小-4kb,同一个域名下的总Cookie数不超过20个

用途:

在不登陆的情况下,完成服务器对客户端的识别

练习:

​ **需求:**访问网站时给出上一次登陆的信息:如果第一次登陆则显示首次登陆,如果不是第一次则显示上一次登录的时间。

分析:

1.采用Cookie来完成

  • ​ 用它来存储登录信息:setMaxAge (int second)

    2.在服务器端Servlet中判断请求消息的消息头中是否有lastTime这个cookie

  • 有:不是第一次访问

    • 取出cookie的值,响应数据
    • 更新lastTime这个Cookie
  • 没有:第一次访问

    • 响应:欢迎您,您是第一次登录
    • 添加cookie:lastTime=当前时间戳
package org.wdit.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
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;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
* 练习:显示上一次登录时间*/
//注解方式配置Servlet
@WebServlet("/cookie3" )
public class CookieDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     //设置相应编码集
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //获取所有Cookie
        Cookie[] cookies = req.getCookies();
        boolean flag=false;//标记是否有lastTime
        ///3.遍历数组
        if(cookies!=null&&cookies.length>0){
            for(Cookie cookie:cookies){
                //获取cookie名称
                String name = cookie.getName();
                //判断
                if("lastTime".equals(name)){
                    //存在,不是第一次访问
                    //获取值
                    String value = cookie.getValue();
                    //URL解码
                    value = URLDecoder.decode(value, "utf-8");


                    //响应
                    resp.getWriter().write("<h1>您上一次访问的时间是:"+value+"</h1>");
                    //更新lastTime
                    Date date=new Date();
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                    String newDate = sdf.format(date);
                    //进行URL编码
                     newDate = URLEncoder.encode(newDate, "utf-8");
                    cookie.setValue(newDate);
                    //设置cookie存活时长

                      //发送cookie
                    resp.addCookie(cookie);
                    flag=true;

                }
            }
        }

        //第一次访问的情况
        if(cookies==null||cookies.length==0||flag==false){
          //获取时间
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String newDate = sdf.format(date);

            //进行URL编码
            newDate = URLEncoder.encode(newDate, "utf-8");
            System.out.println("编码后:"+newDate);
            //创建Cookie对象
            Cookie cookie=new Cookie("lastTime",newDate);
            //设置cookie存储时长
            cookie.setMaxAge(60*60*24*30);
            //发送cookie
            resp.addCookie(cookie);
            flag=true;
            resp.getWriter().write("<h1>您是第一次登录!</h1>");
        }

    }
}

10.JSP

10.1概述

jsp-java Server Page:java服务器端页面

10.2原理

jsp本质是一个Servlet

10.3脚本

就是定义了JSP中java代码的书写方式

  1. <% 代码 %>:定义java代码,相当于定义在Servlet的service方法中
  2. <% ! 代码 %>:定义java代码,相当于定义在Servlet成员的位置,成员变量,成员方法
  3. <%= 代码 %>:输出语句:使用JSP的内置对象-out(后面讲)

10.4内置对象

概述:

直接在JSP页面中,不需要获取和创建,可以直接使用的对象

分类:

1.request;

2.response;

3.sesssion;

4.out;

5.page;

6.application;

7.pageContext;

8.config;

9.exception

内置对象名真实数据类型作用
requestHttpServletRequest一次请求中共享数据
responseHttpServletResponse响应对象
sessionHttpSession一次会话中共享数据
outJSPWriter输出对象,输出数据到当前页面
pageObject当前页面对象
applicationServletContext所有用户间的共享数据
pageContextPageContext当前页面共享数据,通过该对象可以获取其他8个内置对象
configServletConfigservlet配置对象
exceptionThrowable只有异常页面有该对象

**注意事项:**response.getWriter().write()和out对象,web机制在页面输出时会先考虑response缓冲区

10.5Session

**1.概述:**服务器端会话技术-HttpSession

2.功能:

  • 获取HttpSession对象
    • request.getSession()
  • 使用HttpSession对象
    • void seSetAttribute(String name ,Object obj):存储数据
    • **Object getAttribute(String name)😗*通过参数名获取参数值
    • **void removeAttribute(String name)😗*通过移除参数名删除数据

3.原理:

session的实现依赖于Cookie

第一次发送请求,服务器会创建Session对象,并设置一个唯一的id属性,并在响应时,将Session的id存入到响应头:set-cookie:JSESSIONID=id属性值

第二次发送请求,

cookie中就会有对应的Session id,web服务器读到头信息后,就会将两次请求的Session对象指向同一个Session

4.注意事项:

1.客户端关闭之后,再次开启客户端获取的Session对象是同一个吗?

  • 默认情况下,因为客户端关闭,会话就会结束,进而导致Cookie被清空

  • 如果需要相同,我们可以设置cookie来实现:seMaxAge()

    package org.wdit.session;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.*;
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /*
    * 练习:显示上一次登录时间*/
    //注解方式配置Servlet
    @WebServlet("/session1" )
    public class SessionDemo extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req, resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取session对象
            HttpSession session = req.getSession();
           //设置Cookie存活时长
            Cookie cookie=new Cookie("JSESSIONID",session.getId());
            cookie.setMaxAge(60*60);
            resp.addCookie(cookie);
            System.out.println(session);
    
    
        }
    }
    

2.服务器重启后,两个会话的Sesssion是同一个吗?

  • 因为Session对象会被清空,所以很难相同,但又不不想因为重启服务器而丢失ssession数据
    • 解决:Session的钝化和活化 Tomacat可以自动完成Session的钝化和活化
      • 钝化:将seesion对象序列化到磁盘
      • 活化:在服务器启动后,将session数据文件反序列成Session对象

3.Session什么时候被销毁?

  • 服务器关闭
  • session对象调用invalidate():把自己杀死
  • session默认失效时间30分钟,tomcat–安装目录–config----web.xml

4.特点:

  • Session用于存储一次会话中多次请求的数据,存储在服务器端
  • Session可以存储任意类型的数据,任意大小的数据

5.Session和Cookie的区别

Sesssion存储量大,任意类型

10.6登陆案例优化

1.将验证码的实际内容存储到Session对象中进行共享

2.将错误信息显示在对应标签后

10.7JSP指令

1.用于配置jsp页面 ,导入文件

2.格式:<%@指令名称 属性名1=属性值1 属性名2=属性值2…%>

3.分类:

  • page:配置JSP页面
  • include:页面包含()
  • taglib:导入资源,后面学习JSTL标签就需要使用指令导入

4.page指令:

  • contentType:等同于response.setContentType(),设置响应消息的MIME类型,及编码格式。并且可以设置当前 JSP的编码格式(使用高级开发工具才有的功能)
  • **pageEncoding:**当前页面编码集
  • **language:**java
  • **buffer:**缓冲区大小
  • **import:**导包
  • **erorPage:**当前页面报错,会自动跳转至该属性中指定的页面
  • **isErrorPage:**标识当前页面是否是错误页面,如果为true,则可使用Exception,否则不可以使用exception内置对象

5.taglib指令

  • 我们用于引入标签库,后面我们学习JSTl会用到

    <%@  taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    • prefix:前缀,自定义的

10.8MVC开发模式

早期没有JSP,开发使用Servlet,response输出标签数据,工作量巨大的。后来JSP出现简化了Servlet的开发,开发人员开始过度使用JSP,导致前后端无法分离,并且代码结构混乱,阅读性也非常的差,为了解决这个问题,java开发就借鉴了MVC开发模式,具体的规定了什么代码写在什么位置

1.MVC

  • M:Model模型 JavaBean
    • 完成具体的业务操作:比如查询数据库,封装对象等
  • V:view视图 JSP
    • 展示数据
  • C:Controller控制器Servlet
    • 获取用户请求输入(请求数据)
    • 调用模型
    • 将数据交给视图层展示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u4u5VYLo-1616838285611)(E:\JAVA上课笔记\img\image-20210304202526308.png)]

2.优点:

​ 1.降低耦合性,使代码便于维护

​ 2.复用性高

3.缺点:

​ 1.使架构变得复杂,对程序员要求有所提高

10.9 EL表达式

1.概述:EL-Expression Language表达式语言,JSP本身支持EL表达式

2.作用:替换 和简化页面中的Java代码

3.语法:${表达式}

4.使用:

1.运算

  • 算术运算符:+,-,*,/,%

  • 比较运算符:==,!=

    <h3>算术运算符</h3>
    ${1+2}<br>
    ${1-2}<br>
    ${1/2}<br>
    ${1*2}<br>
    ${1%2}<br>
    <h3>逻辑运算符</h3>
    ${3>4 && 5<6}<br>
    ${3>4 and 5<6}<br>
    
  • 逻辑运算符:&&(and),||(or),!(not)

  • 空运算符:empty,用于判断字符串,集合,数组对象是否为null并且长度是否为0

    2.获取值

  • EL表达式只能从域对象中获取值

  • pageScope---->pageContext

  • requestScope—>Request

  • sessionScope—>session

  • applicationScope—>application

  • 比如:${requestScope.name}

  • ${属性名}:省略域对象,它的取值会按照域的大小从小到大依次去寻找

10.10隐式对象

pageContext:通过这个对象。我们可以获取到其他八个JSP内置对象,再通过request对象ContextPath

${pageContext.request.contextPath}

10.11JSTL标签

1.概述:Java Server pages Standarded Tag Library-JSP标准标签库

2.作用:替换和简化页面Java代码

3.使用:

1.导包

2.使用page指令引入标签库

3.使用标签

4.if标签

  • 属性:
    • test:必须属性,接受boolean表达式
      • 如果true,显示标签体内容,false,则不显示
      • 一般情况下test属性结合EL表达式一起使用
  • 注意:if标签没有else,如果要写else,则需再写一个C:if标签

5.choose

​ 1.域中存储一个值

​ 2.使用<C:choose>

​ 3.在<C:choose>中使用<C:when>------case

  • test:判断域中的值与当前case值的关系
    • true:显示<C:when>标签内容
    • false:继续向下比较,直到都不匹配,显示<C:otherwise>标签内容
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%--
  Created by IntelliJ IDEA.
  User: LENOVO
  Date: 2021/3/4
  Time: 21:48
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>choose标签</title>
</head>
<body>
<%
    request.setAttribute("month",1);
%>
<c:choose>
    <c:when test="${month==1 or month==2 or month==3}">第1季度</c:when>
    <c:when test="${month==4 or month==5 or month==6}">第2季度</c:when>
    <c:when test="${month==7 or month==8 or month==9}">第3季度</c:when>
    <c:when test="${month==10 or month==11 or month==12}">第4季度</c:when>
</c:choose>
</body>
</html>

6.foreach

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: LENOVO
  Date: 2021/3/4
  Time: 22:07
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--for(int i=0;i<100;i++)
属性:
  1.begin:开始值
  2.end结束值(包含)
  3.var:临时变量
  4.step:步长
  5.varStatus:循环状态对象
  6.index:索引从0开始
  7.count:循环次数,从1开始
  练习:打印1-100中所有奇数

  2.遍历容器
  for(String s:StringList)
  属性:
    1.items:容器对象--list集合---StringList
    2.var临时变量----s
    3.varStatus:循环状态对象
       index:
       count:循环次数
  
--%>
<c:forEach begin="1" end="100"  step="2" varStatus="s" var="i">
    ${i}-----${s.index}---${count}<br>
</c:forEach>

<%
    List list=new ArrayList();
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    request.setAttribute("stringList",list);
%>
<c:forEach items="${stringList}" var="s" varStatus="vs">
    ${s.index}-----${vs.count}----${s}
</c:forEach>
</body>
</html>

动态展示信息

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="org.wdit.pojo.User" %>
<%@ page import="java.util.List" %><%--
  Created by IntelliJ IDEA.
  User: LENOVO
  Date: 2021/3/4
  Time: 22:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%
    List<User> list=new ArrayList<>();
    list.add(new User(1,"admin","admin"));
    list.add(new User(1,"hx","123456"));
    list.add(new User(1,"hx","admin"));
    request.setAttribute("list",list);
%>
<table border="1" width="600",align="center">
<tr>
    <th>编号</th>
    <th>用户名</th>
    <th>密码</th>
</tr>
    <c:forEach items="${list}" var="user" varStatus="s">
      <c:if test="${s.count%2==0}">
          <tr bgcolor="#faebd7">
              <td>${user.id}</td>
              <td>${user.usename}</td>
              <td>${user.password}</td>
          </tr>
      </c:if>


        <c:if test="${s.count%2!=0}">
            <tr bgcolor="#f0ffff">
                <td>${user.id}</td>
                <td>${user.usename}</td>
                <td>${user.password}</td>
            </tr>
        </c:if>


    </c:forEach>


</table>
</body>
</html>

11.过滤器

11.1概述:

1.概述:当访问服务器资源时,过滤器可以将请求拦下,进行一些特殊的功能

2.作用:一般用于完成通用的操作,比如登录操作,统一编码处理,过滤敏感字符

11.2快速入门

步骤:

1.定义一个类,实现接口Fileter

2.复写方法

3.配置拦截路径

演示案例:

先创建一个类,实现Fileter接口,启动服务器,如果没有放行代码,则JSP内容将不会给展示

package org.wdit.fileter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo implements  Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("过滤器被执行");
    }

    @Override
    public void destroy() {

    }
}

11.3执行流程

package org.wdit.fileter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebFilter("/*")
public class FilterDemo implements  Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       //对请求信息的处理
        System.out.println("过滤器被执行1");
        //放行
        filterChain.doFilter(servletRequest,servletResponse);
        //响应信息的处理
        System.out.println("过滤器2被执行");
    }

    @Override
    public void destroy() {

    }
}

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BkDIL00G-1616838285611)(E:\JAVA上课笔记\img\image-20210305174849506.png)]

​ 为什么会这样?因为过滤器是对访问数据和响应数据进行处理的,所以访问前,过滤会执行一次,处理request中的对象,jsp页面执行后,过滤器会对response数据进行处理

​ 有一点需要注意的是,过滤器再次执行就从放行语句后开始执行

11.4过滤器的配置:(只讲注解方式)

  • 拦截路径配置

    1.具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器资源才会被执行

    2.拦截目录:/user/* 访问user下的所有资源时,过滤器都会执行

    3.后缀名拦截:*.jsp 访问所有后缀名为jsp时,过滤器都会被执行

    4.拦截所有资源:/* 访问所有资源时,过滤器都会被执行

  • 拦截方式配置:资源被访问的方式:直接访问,转发等

    1.注解配置:

    • 设置dispatcherTypes属性
      • REQUEST:默认值,浏览器直接请求资源
      • FORWARD:转发访问资源
      • INCLUDE:包含访问资源
      • ERROR:错误跳转资源:jsp中配置
      • ASYNC:异步访问资源

11.5过滤器链

这里我们只需了解执行顺序即可

*执行顺序:如果有两个过滤器:1,2
1.过滤器1
2.过滤器2
3.资源被执行
4.过滤器2
5.过滤器1
  • 过滤先后顺序:按照各类字符串的比较顺序。xml配置按照配置先后

二阶段综合练习:图书管理系统

1.三层架构

三层架构也是软件设计代码架构,与MVC类似,学完三层架构,再结合MVC就可以写出比较标准的代码

三层架构将软件分为了三层:

1.表示层:用户看到的界面,用户可以通过界面上的组件和服务器进行交互

2.业务逻辑层:用来处理业务逻辑,不做具体实现

3.数据访问层:操作数据,存储文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9qpV4yBj-1616838285612)(E:\JAVA上课笔记\img\image-20210304231532428.png)]

2.准备工作

1.创建空project–>添加Module–>add…---->web—>WEB-INF

2.导入jar包,配置,工具类

  • mysql连接驱动
  • 连接池
  • JdbcTemplate
  • jstl
  • BeanUtils.jar
  • druid.properties
  • JDBCUtils

3.将静态资源考入到web目录下

4.准备数据库

删除选中

3.分页查询

分析:

1.总记录数(Int totalCount):服务器可以自行查出,不用客服端传递数据

2.总页数(interesting totalPage):服务器无法自行完成,需要客户端传递一个参数:rows

3.每页的数据List

4.当前页码(int currentPage):需要客户端提供给服务器

5.分页查询语句:limit startindex,rows

  • startindex-开始索引:(currentPage-1)*rows

  • rows-查几条

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTp5wlSY-1616838285612)(E:\JAVA上课笔记\img\image-20210305141635118.png)]

4.组合条件查询

1.如何采用统一的方式进行条件拼接:

先定义一个模板 :

String sql=” select *from book where 1=1 “

后面我们可以根据用户的输入选择拼接查询条件

sb.append("and b_user=? ")

2.组合条件查询最终返回什么结果?

PageBean对象

5.上传文件

#控制台中文乱码处理

1.Tomcat设置面板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PsYtbQ1o-1616838285613)(E:\JAVA上课笔记\img\image-20210227230937290.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9mNGD48w-1616838285613)(E:\JAVA上课笔记\img\image-20210227231041475.png)]

2.file–settings

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OhvDVIaN-1616838285614)(E:\JAVA上课笔记\img\image-20210227231158098.png)]

3.help—Edit Custom VM Options

为什么会这样?因为过滤器是对访问数据和响应数据进行处理的,所以访问前,过滤会执行一次,处理request中的对象,jsp页面执行后,过滤器会对response数据进行处理

​ 有一点需要注意的是,过滤器再次执行就从放行语句后开始执行

11.4过滤器的配置:(只讲注解方式)

  • 拦截路径配置

    1.具体资源路径:/index.jsp 只有访问index.jsp资源时,过滤器资源才会被执行

    2.拦截目录:/user/* 访问user下的所有资源时,过滤器都会执行

    3.后缀名拦截:*.jsp 访问所有后缀名为jsp时,过滤器都会被执行

    4.拦截所有资源:/* 访问所有资源时,过滤器都会被执行

  • 拦截方式配置:资源被访问的方式:直接访问,转发等

    1.注解配置:

    • 设置dispatcherTypes属性
      • REQUEST:默认值,浏览器直接请求资源
      • FORWARD:转发访问资源
      • INCLUDE:包含访问资源
      • ERROR:错误跳转资源:jsp中配置
      • ASYNC:异步访问资源

11.5过滤器链

这里我们只需了解执行顺序即可

*执行顺序:如果有两个过滤器:1,2
1.过滤器1
2.过滤器2
3.资源被执行
4.过滤器2
5.过滤器1
  • 过滤先后顺序:按照各类字符串的比较顺序。xml配置按照配置先后

二阶段综合练习:图书管理系统

1.三层架构

三层架构也是软件设计代码架构,与MVC类似,学完三层架构,再结合MVC就可以写出比较标准的代码

三层架构将软件分为了三层:

1.表示层:用户看到的界面,用户可以通过界面上的组件和服务器进行交互

2.业务逻辑层:用来处理业务逻辑,不做具体实现

3.数据访问层:操作数据,存储文件

[外链图片转存中…(img-9qpV4yBj-1616838285612)]

2.准备工作

1.创建空project–>添加Module–>add…---->web—>WEB-INF

2.导入jar包,配置,工具类

  • mysql连接驱动
  • 连接池
  • JdbcTemplate
  • jstl
  • BeanUtils.jar
  • druid.properties
  • JDBCUtils

3.将静态资源考入到web目录下

4.准备数据库

删除选中

3.分页查询

分析:

1.总记录数(Int totalCount):服务器可以自行查出,不用客服端传递数据

2.总页数(interesting totalPage):服务器无法自行完成,需要客户端传递一个参数:rows

3.每页的数据List

4.当前页码(int currentPage):需要客户端提供给服务器

5.分页查询语句:limit startindex,rows

  • startindex-开始索引:(currentPage-1)*rows

  • rows-查几条

    [外链图片转存中…(img-PTp5wlSY-1616838285612)]

4.组合条件查询

1.如何采用统一的方式进行条件拼接:

先定义一个模板 :

String sql=” select *from book where 1=1 “

后面我们可以根据用户的输入选择拼接查询条件

sb.append("and b_user=? ")

2.组合条件查询最终返回什么结果?

PageBean对象

5.上传文件

#控制台中文乱码处理

1.Tomcat设置面板

2.file–settings

3.help—Edit Custom VM Options

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值