java web

总结:

1、tomcat、servlet、jsp的关系:
	tomcat是一个容器,可以运行servlet
	jsp就是servlet
2、Servlet就是开发动态web的一门技术
3、servlet原理(重点)	
	浏览器首次访问web容器,一个servlet类会对应生成一个Servlet对象,容器内部的ServletContext对象由所有的Servlet对象共享
	在servlet中可以获取ServletContext对象,也可以给ServletContext对象赋值,
	http请求到web容器中会产生两个对象Request、Response
	根据request请求路径映射到对应的servlet对象
	web容器调用该Servlet对象中的service对Requset对象进行处理,判断Request中是什么请求
	如果是get请求则调动doGet方法,手写的doGet方法对Request进行处理,将处理结果赋值给Response对象并返回浏览器
4、转发和重定向
5、cookie 和 session
6、jsp九大内置对象:application、session、pagecontext、request、response、page、out、config、expection
7、MVC架构
8、过滤器
9、监听器

Java web思维导图

在这里插入图片描述

1、Web项目目录结构

在这里插入图片描述
java 代码目录
resources 资源目录
webapp 项目目录
打包之后,编译器讲main下面的java和resources目录中的文件都加载到webapp目录下的WEB-INF下
在这里插入图片描述
java目录和resources目录中的文件都在classes目录中

2、HTTP

响应状态码:

  • 200 请求成功
  • 3xx 请求重定向,请重新到我给你的新的位置去
  • 4xx 找不到资源 404
  • 5xx 服务器代码错误 500 502是网关错误

3、Maven

Maven是项目架构管理工具
目的就是方便我们导jar包的
Maven的核心思想:约定大于配置

4、tomcat和servlet、jsp的关系

  • tomcat是一个容器,运行servlet的平台
  • jsp是servlet的一个变种,你可以认为jsp就是servlet。

总结:tomcat是一能独立运行的程序,他能运行你写的servlet

5、servlet

Servlet就是开发动态web的一门技术
该技术提供了一个Servlet接口 HttpServlet 继承 GenericServlet 继承 Servlet
如果你想开发一个servlet程序,只需要两步:

  • 编写一个类,继承servlet接口
  • 把开发好的java类部署到web服务器中
    编写程序继承Servlet接口
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doget");
        PrintWriter pw = resp.getWriter();
        pw.println("helloServlet");
    }

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

    }
}

编写servlet的映射
为什么需要映射:我们写的是java程序,但是需通过浏览器访问,而浏览器需要链接web服务器,所以需要在web服务中注册我们写的servlet,还需要给他一个浏览器能够访问的路径
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.kayak.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

访问 http://localhost:8080/hello
在这里插入图片描述
servlet原理(重点

  1. 浏览器首次访问web容器,一个servlet类会对应生成一个Servlet对象,容器内部的ServletContext对象由所有的Servlet对象共享
  2. 在servlet中可以获取ServletContext对象,也可以给ServletContext对象赋值,
  3. http请求到web容器中会产生两个对象Request、Response
  4. 根据request请求路径映射到对应的servlet对象
  5. web容器调用该Servlet对象中的service对Requset对象进行处理,判断Request中是什么请求
  6. 如果是get请求则调动doGet方法,手写的doGet方法对Request进行处理,将处理结果赋值给Response对象并返回浏览器

在这里插入图片描述

在这里插入图片描述
可以写多个servlet映射
应用场景:美化404页面,下例中如果访问路径找不到对应的资源,则会走默认路径请求,返回美化后的404页面

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.kayak.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>    ###指定固有的映射路径优先级最高,如果找不到则会走默认处理请求
  </servlet-mapping>

  <servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.kayak.ErrorServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>  ### 默认处理请求
  </servlet-mapping>
public class ErrorServlet extends HttpServlet {

   @Override
   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       PrintWriter writer = resp.getWriter();
       writer.println("<h1>我走丢了</h1>");
   }

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

   }
}

ServletContext

web容器在启动的时候,会为每个web程序都创建一个ServletContext对象,他代表了当前web应用

1. 共享数据

我在这个servlet中保存数据,可以在另外一个servlet中拿到
赋值

public class HelloServlet extends HttpServlet {

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

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

    }
}

取值

public class GetServelt extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String)context.getAttribute("username");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        writer.println(username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
2. 获取初始化参数
 <!--给ServletContext配置一些初始化参数-->
 <context-param>
   <param-name>url</param-name>
   <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
 </context-param>
public class GetServelt extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = (String)context.getInitParameter("url");
        PrintWriter writer = resp.getWriter();
        writer.println(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
3. 请求转发 RequestDispatcher
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        context.getRequestDispatcher("/get").forward(req, resp);
    }

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

    }
}

:转发和重定向的区别
1、转发 路径不变
2、重定向 路径变化
在这里插入图片描述

4、读取资源文件

Properties

  • 在java目录下新建properties
  • 在resources下新建properties
    打包后,这两个配置文件被打包到同一个目录classes,统称这个路径为:classpath:
public class GetServelt extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is = this.getServletContext()
                .getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        resp.getWriter().println(username+":"+password);
    }

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

注:一般情况下在resources下新建properties等配置文件,打包可以被发现
在java下新建properties配置文件,可能会出现打包打不进该配置文件的情况,此时需要配置pom文件

	<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

HttpServletResponse

简单分类
  • 负责想浏览器发送数据的方法
ServletOutputStream getOutputStream();
PrintWriter getWriter()
  • 负责向浏览器发送响应头的方法

  • 相应状态码

常见应用
  • 向浏览器输出消息
  • 下载文件
public class GetServelt extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       String filepath= "D:\\projects\\javaweb\\servlet02\\src\\main\\resources\\相机知识.png";
        String fileName = filepath.substring(filepath.lastIndexOf("\\") + 1);
        FileInputStream inputStream = new FileInputStream(filepath);//读取文件
        //设置resp响应头方式为下载
        resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"utf-8"));
        ServletOutputStream outputStream = resp.getOutputStream();
        int len ;
        byte[] buffer = new byte[1024];
        while ((len=inputStream.read(buffer))>0){
            //输出resp数据
            outputStream.write(buffer,0,len);
        }
        inputStream.close();
        outputStream.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  • 验证码功能
public class GetServelt extends HttpServlet {

    @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.BLACK);
        //填充
        g.fillRect(0, 0, 80, 20);
        //设置颜色和字体
        g.setColor(Color.BLUE);
        g.setFont(new Font(null, Font.BOLD, 20));
        //写入数据
        g.drawString(getRandomNum(), 0, 20);
        //设置以格式响应
        resp.setContentType("image/jpg");
        //设置缓存不启用
        resp.setDateHeader("expires", -1);
        resp.setHeader("Cache-control", "no-cache");
        resp.setHeader("Pragma", "no-cache");

        ImageIO.write(image, "jpg", resp.getOutputStream());
    }

    private String getRandomNum() {
        Random random = new Random();
        String s = random.nextInt(999999) + "";
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < 6 - s.length(); i++) {
            buffer.append("0");
        }
        return buffer.append(s).toString();
    }

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

在这里插入图片描述

  • 实现重定向(重点
    在这里插入图片描述
    一个web资源-B收到客户端A请求后,B他会通知客户端A去请求另一个web资源-C,这个过程叫重定向
    常见场景:登陆
public class GetServelt extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       /* 实现原理
        resp.setHeader("location","/index.jsp");
        resp.setStatus(302);
        */
        resp.sendRedirect("/index.jsp");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

在这里插入图片描述

HttpServletRequest

常见应用
  • 获取参数
public class GetServelt extends HttpServlet {

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

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbys = req.getParameterValues("hobbys");
        System.out.println("*******************");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        req.getRequestDispatcher("/success").forward(req,resp);
    }
}
  • 请求转发
 req.getRequestDispatcher("/success").forward(req,resp);

转发和重定向

相同:

  1. 都可以实现页面的跳转

不同:

  1. 转发,url不变,由HttpServletRequest对象的方法转发,可以携带原有的req参数
    例如:登陆功能
    如果验证成功,则重定向到主页;
    如果验证失败,则转发到登陆页面,原有req的参数可以展示到用户名和密码输入栏中;
  2. 重定向,url改变,由HttpServletResponse对象的方法重定向,

Cookie、Session

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

有状态会话:

网站怎么证明你来过?两种方式:

  • 服务端给客户端一个信件,客户端下次访问服务端时带上信件就可以访问了 (cookie 保存在客户端)
  • 服务端登记你来过了,下次你来我匹配你就可以访问了 (session 保存在服务端)

保存会话的两种技术

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

  • session:服务端技术,可以保存用户的会话信息,我们可以把信息或数据放到session中

常见应用:网站登录之后,下次在访问就不用登陆了,第二次访问直接就上去了

Cookie

在这里插入图片描述

  1. 从请求中拿到cookie信息
  2. 服务器相应给客户端cookie
Cookie[] cookies = req.getCookies();
cookie.getName();
cookie.getValue();
Cookie cookie = new Cookie("", "");
cookie.setMaxAge(0);
resp.addCookie(cookie);

cookie一般保存在客户端本地用户目录下
思考:
一个网站cookie是否存在上限,

  1. 一个cookie只能保存一条信息
  2. 一个web站点可以给客户端发送多个cookie,最多存放20个cookie
  3. cookie大小限制在4kb
  4. 浏览器上限可以存300个cookie

删除cookie

  1. 不设置有效期,关闭浏览器,cookie自动失效
  2. 设置有效期为0

编码解码:

URLEncoder.encode("您是第一次登陆","utf-8")
URLDecoder.decode(cookie.getValue(),"utf-8");
Session(重点)

在这里插入图片描述
Session由服务器创建,当一个用户(浏览器)访问服务器时,由服务器创建一个该用户独有的Session对象,并将该Session对象的sessionId保存在cookie中发送给用户,这样该用户独有的sessionId就可以凭借Id访问服务器资源

Session和Cookie的区别:

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

使用场景:

  • 保存一个登陆用户信息
  • 购物车
  • 在整个网站中经常使用的数据,我们将他保存在session中

Session中的方法:

 HttpSession session = req.getSession();
 session.setAttribute("name","wanghan");
 session.removeAttribute("name");
 String sessionId = session.getId();
 //注销 Session注销之后,服务器会为该用户马上创建一个新的Session
 session.invalidate();

web.xml中配置Session的失效时间

<session-config>
    <!--单位为分钟-->
    <session-timeout>1</session-timeout>
  </session-config>

servletContext:可以保存多用户的数据,多用户共享(封装为applicationContext)应用服务级别的作用域(所有访问该应用的用户共享)
Session:保存单用户的数据,用户级别作用域
在这里插入图片描述

6、JSP

什么是JSP

java server page:

JSP原理

JSP实质上就是一个Servlet,当浏览器首次访问JSP页面时,web容器会便宜JSP页面,生成一个jsp的.java文件和.class文件,即一个Servlet类
该servlet类中内置了几个属性:pageContext、session、application、config、out、page、response、request等属性
在这里插入图片描述

public final class success_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

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

    final javax.servlet.jsp.PageContext pageContext;  //pageContext对象
    javax.servlet.http.HttpSession session = null;    //session对象
    final javax.servlet.ServletContext application;   //application对象
    final javax.servlet.ServletConfig config;         //config对象
    javax.servlet.jsp.JspWriter out = null;           //out对象
    final java.lang.Object page = this;               //page对象
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
      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;

      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>success!</h2>\n");
      out.write("\n");
      out.write("</body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

在JSP页面中:
只要是java代码就会原封不动的输出
只要是html代码就会转换为:

out.write("<html>\n");

这样的格式输出到浏览器中

JSP基础语法

JSP表达式

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

jsp脚本片段

<%--jsp脚本片段--%>
<%
int a = 0;
for (int i = 0; i < 100; i++) {
  a = a + i;
}
%>

jsp脚本片段再实现

<%--jsp脚本片段再实现--%>
<%
  int a = 0;
  for (int i = 0; i < 100; i++) {
    a = a + i;
  }
%>
<%
 a=1000;
%>

jsp脚本片段嵌入html

<%--jsp脚本片段嵌入html--%>
<%
  int a = 0;
  for (int i = 0; i < 100; i++) {
    a = a + i;
  
%>
<h1>现在是北京时间:<%= new java.util.Date()%></h1>
<%
  }
%>

jsp声明
jsp声明:会被编译到jsp生成的java的类中!其他的语法代码会被编译到java类下的_jspService方法中

<%!
static {
  System.out.println("****");
}
private int a = 0;
public void wanghan(){
  System.out.println("*************88");
}

定制错误界面

<%@ page errorPage="error.jsp" %>

web.xml定制错误界面

 	<error-page>
        <error-code>500</error-code>
        <location>/error.jsp</location>
    </error-page>
    <error-page>
        <error-code>400</error-code>
        <location>/index.jsp</location>
    </error-page>

导包

<%@ page import="java.util.Date" %>

page下面还有很多的属性

<%--@include是将三个页面编译成一个页面
三个页面中定义相同名称的变量会造成变量名冲突的错误
--%>
<%@include file="header.jsp" %>
<h1>主题</h1>
<%@include file="footer.jsp" %>
<%--jsp标签
将三个页面拼接
三个页面里面定义的java变量互不影响
--%>
<jsp:include page="header.jsp"/>
<h1>主题</h1>
<jsp:include page="footer.jsp"/>

jsp 9大内置对象

  • pageContext 存数据
  • request 存数据
  • reponse
  • session 存数据
  • application 存数据
  • config
  • page 几乎不用,了解
  • out
  • exception
<%
    pageContext.setAttribute("a", "1");//保存的数据只在页面上有效
    request.setAttribute("b", "2");//保存的数据在一个请求中有效
    session.setAttribute("c", "3");//保存的数据在一个浏览器中有效
    application.setAttribute("d", "4");//保存的数据在同一个servlet web服务中有效
%>
<%
    //从底层到高层作用域:pageContext-request-session-application
    String a = (String)pageContext.findAttribute("a");
    String b = (String)pageContext.findAttribute("b");
    String c = (String)pageContext.findAttribute("c");
    String d = (String)pageContext.findAttribute("d");
%>

JSP标签、JSPL标签、EL表达式

EL表达式:

  • 获取数据
  • 执行运算
  • 获取web开发常用对象

JSP标签

<jsp:forward page="a.jsp">
    <jsp:param name="aa" value="1"/>
    <jsp:param name="bb" value="2"/>
</jsp:forward>

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

  • 核心标签
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 格式化标签
  • sql标签
  • xml标签

7、MVC三层架构

什么是MVC :model、view、controller
在这里插入图片描述

Model

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

View

  • 展示数据
  • 提供链接发起Servlet请求

Controller(Servlet)

  • 接收用户请求:(req:请求参数、Session信息)
  • 交给业务层对应的代码去处理数据
  • resp响应,控制视图的跳转

8、Filter(过滤器)

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

  • 处理中文乱码
  • 拦截垃圾请求
    在这里插入图片描述

public class FilterTest implements Filter {
    //初始化 web服务器启动,就已经初始化了,随时等候过滤对象出现
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    //FilterChain:链
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        chain.doFilter(request,response);//让我们的请求继续往下走,如果不写,程序到这里就被拦截住了
    }
    //销毁 web服务器关闭时,过滤会被销毁
    public void destroy() {

    }
}

在web.xml中配置自定义的Fiter

 	<filter>
        <filter-name>b</filter-name>
        <filter-class>com.kayak.FilterTest</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>b</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

9、监听器 Listener

实现一个监听器接口;
接口有很多种;

场景:记录在线人数

 public class ListenerTest implements HttpSessionListener {
   //创建session监听
    //一旦创建一个session就会触发一次这个事件
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        HttpSession session = se.getSession();
        System.out.println(session.getId());
        Integer count = (Integer) context.getAttribute("count");
        if(count==null){
            count=1;
        }else{
            count=count+1;
        }
        context.setAttribute("count",count);
    }
    //销毁session监听
    //一旦销毁session就会触发一次这个事件
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext context = se.getSession().getServletContext();
        Integer count = (Integer) context.getAttribute("count");
        if(count==null){
            count=0;
        }else{
            count=count-1;
        }
        context.setAttribute("count",count);
    }
}

在web.xml中的配置

	<listener>
        <listener-class>com.kayak.ListenerTest</listener-class>
    </listener>
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>

应用:监听器在GUI中的使用

public class Test {
    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(Color.red);
        panel.setBounds(150, 150, 250, 250);
        panel.setBackground(Color.cyan);

        frame.add(panel);
        frame.setVisible(true);
        //监听关闭事件
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(1);
            }
        });
    }
}

监听windows的关闭事件
在这里插入图片描述

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

  • 监听器:在GUI编程中经常使用
  • 过滤器:实现登陆权限拦截

思路:

  1. 登陆的时候在session中set登陆属性
  2. 注销的时候移除session中的登陆属性
  3. 自定义拦截器,拦截目标资源,当访问目标资源时,过滤器拦截到请求,在过滤器中获取session,判断session中是否有登陆属性,如果有就放行,如果没有就在resp对象中重定向到登陆页面
  4. login.jsp logout.jsp 与目标资源分开存放,目标资源存在特定目录中如sys,过滤器在web.xml中设置过滤url如下:
 	<filter-mapping>
        <filter-name>b</filter-name>
        <url-pattern>/sys/*</url-pattern>
    </filter-mapping>
public class Login extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String user = req.getParameter("user");
        HttpSession session = req.getSession();
        if(user.equals("admin")){
            session.setAttribute("author","admin");
            resp.sendRedirect("/jsp01_war_exploded/sys/main.jsp");
        }else{
            resp.sendRedirect("/jsp01_war_exploded/a.jsp");
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
public class Logout extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().removeAttribute("author");
        resp.sendRedirect("login.jsp");
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
public class FilterTest implements Filter {
    //初始化
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    //FilterChain:链
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        if(req.getSession().getAttribute("author")==null){
            resp.sendRedirect("../login.jsp");
        }
        chain.doFilter(req,resp);//让我们的请求继续往下走,如果不写,程序到这里就被拦截住了
    }
    //销毁
    public void destroy() {

    }
}

JDBC

编译sql

 public static void main(String[] args) throws ClassNotFoundException, SQLException {

       String url="jdbc:mysql://localhost:3306/jdbc";
       String username="wanghan";
       String password="123456";
       Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection(url, username, password);
        Statement st = con.createStatement();
        String sql = "select * from user";
        ResultSet rs = st.executeQuery(sql);

        while (rs.next()){
            System.out.println(rs.getInt(1));
            System.out.println(rs.getString(2));
            System.out.println(rs.getString(3));
            System.out.println(rs.getDate(4));
        }

        rs.close();
        st.close();
        con.close();
    }

预编译sql

可以防止sql注入

 public static void main(String[] args) throws ClassNotFoundException, SQLException {

        String url = "jdbc:mysql://localhost:3306/jdbc";
        String username = "wanghan";
        String password = "123456";
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection(url, username, password);
        String sql = "select * from user where id = ?";
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setInt(1, 10);
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            System.out.println(rs.getInt(1));
            System.out.println(rs.getString(2));
            System.out.println(rs.getString(3));
            System.out.println(rs.getDate(4));
        }
        rs.close();
        ps.close();
        con.close();
    }

JDBC事务

要么都成功,要么都失败

  • 开启事务
  • 提交事务
  • 回滚事务
  • 关闭事务
public static void main(String[] args) throws ClassNotFoundException, SQLException {

        String url = "jdbc:mysql://localhost:3306/jdbc";
        String username = "wanghan";
        String password = "123456";
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = DriverManager.getConnection(url, username, password);
            con.setAutoCommit(false);//开启事务
            String sql = "delete * from user where id = ?";
            ps = con.prepareStatement(sql);
            ps.setInt(1, 10);
            int i = ps.executeUpdate(sql);//执行第一条sql
            ps.setInt(1, 11);
            int ii = ps.executeUpdate(sql);//执行第二条sql
            con.commit();//提交事务
        } catch (Exception e) {
            con.rollback();//事务回滚
        }finally {
            ps.close();
            con.close();
        }
    }

BaseDao

public class BaseDao {

    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    static {
        Properties p = new Properties();
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("properites");
        try {
            p.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        driver=p.getProperty("driver");
        url = p.getProperty("url");
        username = p.getProperty("username");
        password = p.getProperty("password");
    }

    //获取链接
    public static Connection myConnection() throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        return DriverManager.getConnection(url, username, password);
    }
    //编写查询公共类
    public static ResultSet execute(Connection connection,PreparedStatement preparedStatement, ResultSet resultSet,String sql,Object[] params) throws SQLException {
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1,params[i]);
        }
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }
    //编写增删改公共类
    public static int update(Connection connection,PreparedStatement preparedStatement, String sql,Object[] params) throws SQLException {
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            preparedStatement.setObject(i+1,params[i]);
        }
        int rows = preparedStatement.executeUpdate();
        return rows;
    }
    //关闭链接资源公共类
    public static Boolean disConnect(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet){
        Boolean flag= true;
        if(resultSet!=null){
            try {
                resultSet.close();
                resultSet=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        if(preparedStatement!=null){
            try {
                preparedStatement.close();
                preparedStatement=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        if(connection!=null){
            try {
                connection.close();
                connection=null;
            } catch (SQLException e) {
                e.printStackTrace();
                flag=false;
            }
        }
        return flag;
    }
    ```
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值