JavaWeb-狂神-P11

1.共享数据

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //this.getInitParameter(); 初始化参数
        //this.getServletConfig();  Servlet配置
        //this.getServletContext(); Servlet上下文
        ServletContext servletContext = this.getServletContext();
        String username="尚硅谷";//数据
        servletContext.setAttribute("username",username);
    }

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

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        String username = (String) servletContext.getAttribute("username");

        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    
        servlet1
        HelloServlet

    

    
        servlet1
        /one
    

2.获取初始化参数

    
    
        url
        jdbc.mysql:://localhost:3306/mybatis
    
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();

        String url = servletContext.getInitParameter("url");
        resp.getWriter().print(url);
    }

3.请求转发

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.print("进入了ServletDemo04");
        ServletContext servletContext = this.getServletContext();
        servletContext.getRequestDispatcher("/three").forward(req,resp);//转发的请求路径,调用forward实现请求转发


    }

JavaWeb-狂神-P11_第1张图片

 4.读取资源文件

properties

  • 在java目录下新建properties
  • 在resources目录下新建properties

发现:都被打包到了同一个路径下:classes,我们俗称这个路径为类路径classpath;

需要一个文件流;

username=qinjiang
password=123456
public class ServletDemo05 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/db.properties");//路径区分大小写
        Properties pros = new Properties();
        pros.load(is);
        String username = pros.getProperty("username");
        String password = pros.getProperty("password");

        resp.getWriter().print(username+password);
    }

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

访问测试即可ok;

P12

1.HttpServletReponse

web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse

1.简单分类

负责向浏览器发送数据的方法

ServletOutputStream getOutputStream() throws IOException;

    PrintWriter getWriter() throws IOException;

 负责向浏览器发送响应头的方法

    void setCharacterEncoding(String var1);

    void setContentLength(int var1);

    void setContentLengthLong(long var1);

    void setContentType(String var1);

    void setBufferSize(int var1);
    
    void setDateHeader(String var1, long var2);

    void addDateHeader(String var1, long var2);

    void setHeader(String var1, String var2);

    void addHeader(String var1, String var2);

    void setIntHeader(String var1, int var2);

    void addIntHeader(String var1, int var2);

    void setStatus(int var1);

 响应的状态码

    int SC_CONTINUE = 100;
    int SC_SWITCHING_PROTOCOLS = 101;
    int SC_OK = 200;
    int SC_CREATED = 201;
    int SC_ACCEPTED = 202;
    int SC_NON_AUTHORITATIVE_INFORMATION = 203;
    int SC_NO_CONTENT = 204;
    int SC_RESET_CONTENT = 205;
    int SC_PARTIAL_CONTENT = 206;
    int SC_MULTIPLE_CHOICES = 300;
    int SC_MOVED_PERMANENTLY = 301;
    int SC_MOVED_TEMPORARILY = 302;
    int SC_FOUND = 302;
    int SC_SEE_OTHER = 303;
    int SC_NOT_MODIFIED = 304;
    int SC_USE_PROXY = 305;
    int SC_TEMPORARY_REDIRECT = 307;
    int SC_BAD_REQUEST = 400;
    int SC_UNAUTHORIZED = 401;
    int SC_PAYMENT_REQUIRED = 402;
    int SC_FORBIDDEN = 403;
    int SC_NOT_FOUND = 404;
    int SC_METHOD_NOT_ALLOWED = 405;
    int SC_NOT_ACCEPTABLE = 406;
    int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
    int SC_REQUEST_TIMEOUT = 408;
    int SC_CONFLICT = 409;
    int SC_GONE = 410;
    int SC_LENGTH_REQUIRED = 411;
    int SC_PRECONDITION_FAILED = 412;
    int SC_REQUEST_ENTITY_TOO_LARGE = 413;
    int SC_REQUEST_URI_TOO_LONG = 414;
    int SC_UNSUPPORTED_MEDIA_TYPE = 415;
    int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    int SC_EXPECTATION_FAILED = 417;
    int SC_INTERNAL_SERVER_ERROR = 500;
    int SC_NOT_IMPLEMENTED = 501;
    int SC_BAD_GATEWAY = 502;
    int SC_SERVICE_UNAVAILABLE = 503;
    int SC_GATEWAY_TIMEOUT = 504;
    int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

2.下载文件

1.向浏览器输出消息(一直在讲,见上面的例子)

2.下载文件

 1.要获取下载文件的路径

 2.下载的文件名是啥?

 3.设置想办法让浏览器能够支持下载我们需要的东西

 4.获取下载文件的输入流

 5.创建缓冲区

 6.获取OutputStream对象

 7.将FileOutputStream流写入buffer缓冲区

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//          1.要获取下载文件的路径
        String realPath =  "D:\\ideaWorkSpace\\javaweb-servlet-01\\response\\src\\main\\resources\\狂神.png";
        System.out.print("下载文件的路径:"+realPath);

//          2.下载的文件名是啥?
        String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
//          3.设置想办法让浏览器能够支持(Content-disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
        resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//          4.获取下载文件的输入流
        FileInputStream fis = new FileInputStream(realPath);
//          5.创建缓冲区
        int len=0;
        byte[] buffer = new byte[1024];
//          6.获取OutputStream对象
        ServletOutputStream os = resp.getOutputStream();
//          7.将FileOutputStream流写入buffer缓冲区
        while ((len=fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }
        os.close();
        fis.close();
    }

 3.验证码功能

验证怎么来的?

  • 前端实现
  • 后端实现
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //如何让浏览器5秒自动刷新一次
        resp.setHeader("refresh","3");

        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();//笔
        //设置图片的背景颜色
        g.setColor(Color.white);
        g.fillRect(0,0,80,20);
        //给图片写数据
        g.setColor(Color.blue);
        g.setFont(new Font(null, Font.BOLD,20));
        g.drawString(makeNum(),0,20);

        //告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/ PNG");
        //网站存在缓存,不让浏览器缓存
        resp.setDateHeader("expires",-1);
        resp.setHeader("cache- Control","no-cache");//缓存策略
        resp.setHeader("pragma","no-cache");

        //把图片写给浏览器

        boolean png = ImageIO.write(image, "png", resp.getOutputStream());


    }

 4.实现重定向

JavaWeb-狂神-P11_第2张图片

一个web资源收到客户端请求后,他会通知客户端去访问另外一个web资源,这个过程叫重定向

 常见场景:

  • 用户登录
void sendRedirect(String var1) throws IOException;

JavaWeb-狂神-P11_第3张图片

 测试:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        resp.setHeader("Location","/image");
        resp.setStatus(302);
        */
        resp.sendRedirect("/image");//重定向
    }

 面试题:请你聊聊重定向和转发的区别?

相同点:

  • 都会跳转到别的页面

不同点:

  • 请求转发的时候,url不会产生变化
  • 重定向的时候,url会产生变化

小贴士:tomcat9控制台中文乱码,可以解决,但不建议

1、找到${CATALINA_HOME}/conf/logging.properties

2、找到java.util.logging.ConsoleHandler.encoding = UTF-8

      修改为java.util.logging.ConsoleHandler.encoding = GBK

简单实现登录重定向

注意在转发的时候如果在点击提交按钮的时候报404错误,并且是因为输入pageContext.request.contextPath的这一段,是因为web.xml的版本问题

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

        //处理请求
        String username=req.getParameter("username");
        String password=req.getParameter("password");

        System.out.print(username+password);

        //重定向的时候一定要注意,路径问题,否则404
        resp.sendRedirect("/r/success.jsp");
    }
 
      Test
      com.atguigu.servlet.RequestTest
    
    
      Test
      /login
    


    登录页面
    




Hello World!

<%--这里提交的路径,需要寻找到项目的路径--%> <%--${pageContext.request.contextPath}代表当前的项目 --%>
用户名: 密码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


Success

2.HttpServletRequest

JavaWeb-狂神-P11_第4张图片

 JavaWeb-狂神-P11_第5张图片

1.获取前段传递的参数 

JavaWeb-狂神-P11_第6张图片

2.请求转发

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        String[] hobbys = req.getParameterValues("hobbys");

        //后台接收中文乱码问题

        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("===================");
        //重定向
//        resp.sendRedirect();
        //转发
//        this.getServletContext()
        //通过请求转发
        //这里的斜杠代表当前的web应用
        req.getRequestDispatcher("/Success.jsp").forward(req,resp);

    }

面试题:请你聊聊重定向和转发的区别

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会产生变化 307
  • 重定向的时候,url地址会发生变化 302

7.Cookie、Session

7.1会话

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;

你能怎么证明你是谁?

1.身份证 

一个网站,怎么证明你来过?

客户端        服务端

1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie

2.服务器登记你来过了,下次你来的时候我来匹配你;seesion

7.2、保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

seesion

  • 服务器技术、利用这个技术,可以保存用户的会话信息?我们可以把信息或数据放在Session中!

常见场景:网站登录之后,你下次不用登录了,第二次访问直接就上了!

7.3Cookie

1.从请求中拿到Cookie信息

2.服务器响应给客户端Cookie

 Cookie[] cookies = req.getCookies();//获得Cookie
 cookie.getName()//获得Cookie中的key
 cookie.getValue()//获得Cookie中的value
 out.write(date.toLocaleString());//date类型转String
 cookie.setMaxAge(24*60*60);//设置有效期
 Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");//新建Cookie
 resp.addCookie(cookie);//响应给客户端一个Cookie

cookie:一般会保存在本地的用户目录下appdata;

一个网站的Coolie是否存在上限!聊聊细节问题

  • 一个Cookie只能保存一个信息;
  • 一个web站点可以给浏览器发送多个cookie,每个站点最多存放20个Cookie
  • Cookie大小有限制4kb;
  • 300个Cookie浏览器上限

删除Cookie

  • 不设置有限期,关闭浏览器,自动失效;
  • 设置有效期时间为0

编码解码:

URLEncoder.encode("秦疆","utf-8")//编码
URLDecoder.decode(cookie.getValue(),"utf-8")//解码

7.4、Session(重点)

什么是Session:

  • 服务器会给每一个用户(浏览器)创建一个Session对象;
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
  • 用户登录之后,整个网站它都可以访问!--->保存用户的信息;保存购物车的信息...

Session

JavaWeb-狂神-P11_第7张图片

Session和Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存
  • Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建 

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 经常在整个项目中或网站中经常使用的数据,保存在Session中;

使用Session:

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //解决乱码问题
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;Character=utf-8");


        //得到Session
        HttpSession session = req.getSession();

        //给Session中存东西
        session.setAttribute("name",new Person("秦疆",1));

        //获取Session的ID
        String id=session.getId();

        //判断Session是不是新创建
        if(session.isNew()){
            resp.getWriter().write("Session创建成功,id="+id);
        }else{
            resp.getWriter().write("Session已经在服务器中存在"+id);
        }

        //Session做了什么
//        Cookie jsessionid = new Cookie("JSESSIONID", "6815754D02889928D1B75B3EADDFCB07");
//        resp.addCookie(jsessionid);
    }


        //得到Session
        HttpSession session = req.getSession();
        HttpSession session1 = req.getSession();
        Person name = (Person) session1.getAttribute("name");

        resp.getWriter().write(name.toString());





        HttpSession session = req.getSession();
        session.removeAttribute("name");
        //手动注销session
        session.invalidate();

会话自动过期:web.xml配置

  
  
    
    15
  

JavaWeb-狂神-P11_第8张图片

 8.JSP

Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态Web技术!

最大的特点:

  • 写JSP就像在写HTML
  • 区别:
    • HTML只给用户提供静态的数据
    • JSP页面可以嵌入JAVA代码,为用户提供动态数据;

8.2、JSP原理

思路:JSP到底怎么执行的!

  • 代码层面没有任何问题
  • 服务器内部工作
  • tomcat中有一个work目录;
  • IDEA中使用Tomcat的会在IDEA中产生一个work目录

JavaWeb-狂神-P11_第9张图片

 我电脑的地址:

C:\Users\q\.IntelliJIdea2017.3\system\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\s\org\apache\jsp

发现页面转变成了Java程序! 

JavaWeb-狂神-P11_第10张图片

 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!

JSP最终也会转换成一个Java类!

JSP本质也是一个Servlet

  //初始化
  public void _jspInit() {
  }

  //销毁
  public void _jspDestroy() {
  }

  //JSPService
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

1.判断请求

2.内置了一些对象

    final javax.servlet.jsp.PageContext pageContext;    //页面上下文
    javax.servlet.http.HttpSession session = null;      //session
    final javax.servlet.ServletContext application;     //applicationContext
    final javax.servlet.ServletConfig config;           //config
    javax.servlet.jsp.JspWriter out = null;             //out
    final java.lang.Object page = this;                 //page:当前页面
    HttpServletRequest request                          //请求
    HttpServletResponse response                        //响应

3.输出页面前增加的代码

      response.setContentType("text/html");        //设置响应的页面类型
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);            
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

4.以上的这些个对象我们可以在JSP页面中直接使用

JavaWeb-狂神-P11_第11张图片

 在JSP页面中:

只要是JAVA代码就会原封不动的输出,只要是HTML代码就会被转为:

out.write("\r\n");

这样的格式,输出到前端!

8.3JSP基础语法

任何语言都有自己的语法,JAVA中有...JSP作为java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可!),java所有语法都支持()

JSP表达式

  <%--JSP表达式
  作用:用来将程序的输出,输出到客户端
  <%= 变量或者表达式%>
  --%>
  <%= new java.util.Date()%>

JSP脚本片段

  <%-- jsp脚本片段--%>

  <%
   int sum=0;
   for (int i=0;i<=100;i++){
       sum+=i;
   }
   out.println("

Sum="+sum+"

"); %>

脚本片段的再实现

<% int x=10;
out.println(x);
%>
  

这是一个JSP文档

<% int y=20; out.println(y);%>
<%--在代码嵌入HTML元素--%> <% for (int i = 0; i <100 ; i++) { %>

hello kuangshen <%=i%>

> <% } %>

JSP声明

  <%!
  static {
    System.out.println("Loding Servlet");
  }

  private int globalVar=0;

  public void kuang(){
    System.out.println("进入狂method");
  }
  %>

JSP声明:会被编译到JSP生成的JAVA类的类中!其他的就会被生成到_jspService方法中!

在JSP中,嵌入JAVA代码即可!

<%%>
<%=%>
<%!%>

<%--注释--%>

JSP的注释,不会在客户端显示,HTML就会!

8.4、JSP指令

<%@ page isErrorPage="true" %>

<%-- @include 会将两个页面合二为一 定义的变量或常量不能重名--%>
    <%@include file="/common/header.jsp"%>
    

网页主体

<%@include file="common/footer.jsp"%> <%--jsp:include拼接页面,本质还是三个 定义的变量或常量可以重名--> <%--jsp标签--%>

8.5、九大内置对象

  • PageContext                             存东西
  • Requset                                     存东西
  • Response
  • Session                                      存东西
  • Application 【ServletContext】 存东西
  • config 【ServletConfig】
  • out
  • page                                        不用了解
  • Exception
    pageContext.setAttribute("name1","one");//保存的数据只在一个页面中有效
        request.setAttribute("name2","two");//保存的数据只在一次请求中有效,请求转发会携带这个数据
        session.setAttribute("name3","three");//保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
        application.setAttribute("name4","four");//打开的数据只在服务器中有效,从打开服务器到关闭服务器

 request:客户端向服务器发送请求,请求的数据,用户看完就没用了,比如:新闻

session:客户端向服务器发送请求,请求的数据,用户用完一会儿还会用,比如:购物车;Hystrix

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;

8.6、JSP标签、JSTL标签、EL表达式

        
        
            javax.servlet.jsp
            javax.servlet.jsp-api
            2.3.3
        

        
        
        
            taglibs
            standard
            1.1.2
        

        
        
        
            javax.servlet.jsp.jstl
            jstl-api
            1.2
        

EL表达式:${ }

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
  • 调用java方法(不常用)

JSP标签

<%----%>

<%--
http://Locahost:8080/jsptag.jsp?name=kuangshen&shr=22
--%>

    
    

JSTL表达式

JSTL标签库的是用就是为了弥补HTML标签的不足;它自定义了许多标签,可以供我们使用,标签的功能就和java代码一样!

格式化标签

SQL标签

XML标签

核心标签(必须掌握)

JavaWeb-狂神-P11_第12张图片

 JSTL标签库使用步骤:

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat也需要引入jstl的包,否则会报错:JSTL解析错误
  • c:if

    Title



if测试


<%-- EL表达式获取表单中的数据 ${ <%--判断如果提交的用户名是管理员,则登录成功--%> <% if ("admin".equals(request.getParameter("username"))) { out.print("登陆成功"); } %>
  •  c:choose
  • c:when
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title



<%--定义一个变量score,值为90--%>



    
        你的成绩为优秀
    
    
        你的成绩为良好
    
    
        你的成绩为合格
    
    
        你的成绩为不合格
    
    


c:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


<%
    ArrayList people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    people.add(2,"王五");
    people.add(3,"赵六");
    people.add(4,"田七");
    request.setAttribute("list",people);
%>

<%--
var     每一次遍历出来的变量
items   要遍历的对象
begin   哪里开始
end     到哪里
step    步长
--%>

     


9、JavaBean

实体类

JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法;
  • 一般用来和数据库的字段做映射 ORM;

ORM编程思想:对象关系映射

  • 表--->类
  • 字段--->属性
  • 行记录--->对象
id name age address
1001 张小龙 39 深圳
1002 宫玉龙 25 凤阳
1003 陈小小 24 湖州

class People{
    private int id;
    private String name;
    private int age;
    private String address;

    private People(int id,String name, int age, String address) {
                this.id=id;
    }
    private People() {
                
    }
}

10、MVC三层加工

什么是MVC?     Model View Controller 模型、视图、控制器

10.1、早些年三层架构

JavaWeb-狂神-P11_第13张图片

 用户直接访问控制层、控制层就可以直接操作数据库;

servlet --->CRUD--->数据库
弊端:程序十分臃肿,不利于维护 servlet的代码中:处理请求、响应、视图跳转、处理JDBC、处理业务代码、处理逻辑代码

架构:没有什么是加一层解决不了的!
程序员调用
|
JDBC
|
Mysql Oracle SqlServer ....

10.2、MVC三层架构

JavaWeb-狂神-P11_第14张图片

 Model

  • 业务处理:业务逻辑(Service)
  • 数据持久层:CRUD(Dao)

View

  • 展示数据
  • 提供连接发起Servlet请求(a,from,img...)

Controller

  • 接受用户请求:(req:请求参数、Seesion信息....)
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登录--->接受用户的登录请求--->处理用户的请求(获取用户登录的参数,username、password)---
>交给业务层处理登录业务(判断用户名密码是否正确:事务)--->Dao层查询用户名和密码是否正确---
>数据库

11、Filter(重点)

Shiro安全框架

Filter:过滤器,用来过滤网站的数据;

  • 处理中文乱码

JavaWeb-狂神-P11_第15张图片

 Filter开发步骤:

  1. 导包
  2. 编写过滤器
    1. 导包不要错

JavaWeb-狂神-P11_第16张图片

实现Filter接口,重写对应的方法即可

public class charcterEncodingFilter implements Filter{

    //初始化:web服务器启动,就已经初始化了,随时等待过滤对象出现
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("charcterEncodingFilter初始化");
    }

    //链
    /*
    1.过滤中的所有代码,在过滤特定请求的时候都会执行
    2.必须要让过滤器继续同行
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            response.setCharacterEncoding("utf-8");
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");

        System.out.println("characterEncodingFilter执行前....");
        chain.doFilter(request,response);//让我们的请求继续走,如果不写,程序到这里就被拦截停止!
        System.out.println("characterEncodingFilter执行后....");

    }

    //销毁:web服务器关闭的时候,过滤器会销毁
    @Override
    public void destroy() {
        System.out.println("charcterEncodingFilter已销毁");
    }
}

 3.在web.xml中配置过滤器

    
        characterEncodingFilter
        com.atguigu.filter.charcterEncodingFilter
    

    
        characterEncodingFilter
        
        /servlet/*
    

12、监听器 

实现一个监听器的接口:()

1.编写一个监听器

        实现监听器的接口

//统计网站在线人数:
public class OnLineCountListener implements HttpSessionListener{

    //创建session监听:看你的一举一动
    //一旦创建Session就会触发一次这个事件!
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        System.out.println(se.getSession().getId());
        if (onlineCount==null){
            onlineCount=new Integer(1);
        }else{
            int count= onlineCount.intValue();

            onlineCount =new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }

    //销毁session监听
    //一旦销毁Session就会触发一次这个事件!
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

        ServletContext ctx = se.getSession().getServletContext();
        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount=new Integer(0);
        }else{
            int count= onlineCount.intValue();

            onlineCount =new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);
    }

    /*
    Session销毁:
    1.手动销毁 getSession().invalidate();
    2.自动销毁
    * */
}

2.web.xml中注册监听器

    
        1
    

3.看情况是否使用!

13、过滤器、监听器常见应用

监听器:GUI编程中经常使用;

public class TestPanle {

    public static void main(String[] args) {
        Frame frame = new Frame("中秋节快乐");//新建一个窗体
        Panel panel=new Panel(null);//面板

        frame.setLayout(null);//设置窗体的布局

        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(160,180,140));//设置背景颜色
        panel.setBounds(50,50,300,300);
        panel.setBackground(new Color(255,100,50));//设置背景颜色

        frame.add(panel);

        frame.setVisible(true);

        //监听事件:监听关闭事件

        frame.addWindowListener(new WindowListener() {
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("打开");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("关闭ing");
                System.exit(0);
            }

            @Override
            public void windowClosed(WindowEvent e) {
                System.out.println("关闭ing");
            }

            @Override
            public void windowIconified(WindowEvent e) {

            }

            @Override
            public void windowDeiconified(WindowEvent e) {

            }

            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("激活");
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                System.out.println("未激活");
            }
        });

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
            }
        });
    }

}

用户登录之后才能进入主页!用户注销后就不能进入主页了!

在javaweb编程进行jsp页面跳转时,点击提交按钮无反应,来回检查许多遍相关文件配置,最终发现是将form写成了from,所以有时候细节真的害死人

1.用户登录之后,向Session中放入用户的数据

2.进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req= (HttpServletRequest) request;
        HttpServletResponse resp= (HttpServletResponse) response;
        Object userSession = req.getSession().getAttribute(Constant.USER_SESSION);
        if (userSession==null){
            resp.sendRedirect("/login.jsp");
        }

        chain.doFilter(request, response);
    }

14、JDBC

什么是JDBC:java连接数据库!

JavaWeb-狂神-P11_第17张图片

需要jar包的支持:

java.sql

javax.sql

实验环境搭建:

USE jdbc
CREATE TABLE users(
id INT PRIMARY KEY, 
`name` VARCHAR(40), 
`password` VARCHAR(40),
email VARCHAR(60),
birthday DATE
);

SELECT *FROM users

INSERT INTO users(id,`name`,`password`,email,birthday)
VALUES
(2,'李四','123456','[email protected]','2000-01-10'),
(3,'王五','234567','[email protected]','2001-01-10'),
(4,'赵一','345678','[email protected]','2002-01-10'),
(5,'钱二','456789','[email protected]','2001-01-10')

 导入数据库依赖:

    
        
            mysql
            mysql-connector-java
            8.0.26
        

    

 IDEA中连接数据库:

JavaWeb-狂神-P11_第18张图片

JDBC连接: 

1.配置信息

2.加载驱动

3.连接数据库

4.向数据库发送SQL的对象

5.编写SQL

6.执行查询SQL,返回ResultSet结果集

7.关闭连接,释放资源(一定要做)先开后关

public class TestJdbc {

    public static void main(String[] args) {
        //1.配置信息
        //useUnicode=true&characterEncoding=utf-8解决中文乱码
        String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
        String username="root";
        String password="love521.";

        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            //2.加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //3.连接数据库
            conn = DriverManager.getConnection(url, username, password);
            System.out.println(conn);

            //4.向数据库发送SQL的对象Statement:CRUD
            st = conn.createStatement();
            //5.编写SQL
            String sql="select * from users";

            //6.获取结果集
            rs = st.executeQuery(sql);

            while (rs.next()){
                System.out.print("id="+rs.getObject("id"));
                System.out.print("name="+rs.getObject("name"));
                System.out.print("password="+rs.getObject("password"));
                System.out.print("email="+rs.getObject("email"));
                System.out.println("birthday="+rs.getObject("birthday"));
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //7.关闭连接,释放资源(一定要做)
            if (rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(st!=null){
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

预编译SQL语句:

public class TestJdbc2 {

    public static void main(String[] args) {
        //1.配置信息
        //useUnicode=true&characterEncoding=utf-8解决中文乱码
        String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
        String username="root";
        String password="love521.";

        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            //2.加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //3.连接数据库
            conn = DriverManager.getConnection(url, username, password);
            System.out.println(conn);

            //4.编写SQL
            String sql="insert into users(id,name,password,email,birthday) VALUES (?,?,?,?,?)";
            //5.向数据库发送SQL的对象Statement:CRUD
            PreparedStatement ps = conn.prepareStatement(sql);

            //填充SQL语句并执行
            ps.setInt(1,6);
            ps.setString(2,"qingjiang");
            ps.setString(3,"123456");
            ps.setString(4,"[email protected]");
            ps.setDate(5,new Date(2345653421L));

            int i = ps.executeUpdate();
            if (i>0){
                System.out.println("ok");
            }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //7.关闭连接,释放资源(一定要做)
            if (rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(st!=null){
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

事务

要么都成功,要么都失败

ACID原则:保护数据的安全

开启事务

事务提交 commit()

事务回滚 rollback()

关闭事务

转账:

A:1000

B:1000

A(900)        --->        100        --->        B(1100)

你可能感兴趣的:(web)