JavaWeb笔记

文章目录

  • JavaWeb基础知识
    • 基础准备
    • HTTP
    • Servlet
      • 基本结构与功能
      • Mapping
      • ServletContext
      • HttpServletResponse
      • HttpServletRequest
    • Cookie, Session
      • Cookie
      • Session
    • JSP
      • JSP基础语法和指令
      • 自定义错误页面的跳转
      • 网站头尾
      • JSP内置对象及作用域
      • JSP、JSTL标签、EL表达式
        • JSP标签
        • jstl表达式
    • MVC
    • Filter
      • Filter做权限管理
    • JDBC复习
      • 基础操作
      • 事务


JavaWeb基础知识

结构图
JavaWeb笔记_第1张图片


基础准备

Tomcat

  • 启动:在bin文件夹中打开startup.bat
  • 关闭:shutdown.bat
  • 使用:在网站窗口输入localhost:8080就会出现这个,这个是可以修改的,数字可以改,在System中的host可以改localhost的名字
  • 访问路径:localhost访问的是webapps里面的ROOT文件夹
  • 发布网站: 将自己写的网站放到服务器(tomcat)指定的web应用的文件夹下,就可以访问了

网站是如何访问的

  1. 输入域名:回车
  2. 检查本机路径下C:\Windows\System32\drivers\etc\host有没有域名映射
  3. 有的话就直接返回对应的IP地址,可以直接访问;没有的话就在DNS中查找,找到就返回

网站应有结构
webapps:

  • ROOT
    • kiruto:网站的目录名
    • WEB-INF
      + classes:java程序
      + lib:web应用依赖的jar包
      + web.xml:网站配置文件
    • index.html:默认的首页

HTTP

请求行

  • 请求行中的请求方式:GET
  • 请求方式:Get,Post,HEAD等
    • get:请求能携带的参数比较少,有大小限制,会在浏览器的URL地址栏显示数据内容,不安全但高效
    • post:请求能携带的参数比较多,没有大小限制,不会显示参数,安全但低效。

消息头

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.

响应体
这个不知道有啥用

Accept: 告诉浏览器支持的数据类型
Accept-Encoding:支持那种格式编码 GBK、UTF-8、GB2312等
Cache-Control: 缓存控制
Connection:告诉浏览器,请求完成时断开还是保持连接
HOST: 主机
Refresh:告诉客户端,多久刷新一次
Location:让网页重新定位

响应状态码

  • 200:请求响应成功
  • 3xx:请求重定向,重定向就是转到新给的位置中
  • 4xx:找不到资源
  • 5xx:500是服务器diamagnetic逻辑错误,502是网关错误

动态Web:
JavaWeb笔记_第2张图片

创建Maven配置Tomcat
JavaWeb笔记_第3张图片
JavaWeb笔记_第4张图片
JavaWeb笔记_第5张图片
JavaWeb笔记_第6张图片


Servlet

基本结构与功能

功能:连接业务层和前端,从前端接受参数传递给业务层。

结构servlet.java文件用来写逻辑传参数,web.xml用来注册访问路径。

原理
JavaWeb笔记_第7张图片

继承关系

public abstract class HttpServlet extends GenericServlet {}
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {}

JavaWeb笔记_第8张图片

servlet实现

public class HelloServlet extends HttpServlet {
    // get和pose只是请求实现的不同方式,可以相互调用,业务逻辑都一样
    // 参数:请求、响应,然后还要抛异常
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 响应
        System.out.println("进入了doget");
        PrintWriter writer = resp.getWriter();
        writer.print("hello servlet");
    }
}

web注册


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

web-app>


  
  <servlet>
    
    <servlet-name>helloservlet-name>
    <servlet-class>com.it.servlet.HelloServletservlet-class>
  servlet>

  
  <servlet-mapping>
    
    <servlet-name>helloservlet-name>
    
    <url-pattern>/hellourl-pattern>
  servlet-mapping>

遇到的问题
配置tomcat的时候需要artificial,没有可以自己创建一个,在Project Structure–>Project Settings–>Artifacts–>添加Web Application:Archive,Output directory选择servlet-01\target,Output Layout选择servlet-01.war

Mapping

路径映射有三种方法:

  1. 一个请求可以指定一个映射路径
  
  <servlet-mapping>
    
    <servlet-name>helloservlet-name>
    
    <url-pattern>/hellourl-pattern>
  servlet-mapping>
  1. 可以指定多个映射路径
  
  <servlet-mapping>
    
    <servlet-name>helloservlet-name>
    
    <url-pattern>/hellourl-pattern>
  servlet-mapping>

  <servlet-mapping>
  <servlet-name>helloservlet-name>
    <url-pattern>/hello2url-pattern>
  servlet-mapping>
  1. 使用通配符
    可以写任意也可以不写,通配符的优先级是较低的,指定的固有的路径优先级最高。
  <servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/hello/*url-pattern>
  servlet-mapping>

这样是不行的

    <url-pattern>/*.dourl-pattern>

要把/去掉才可以自定义后缀,*前面什么都不能加

    <url-pattern>*.dourl-pattern>

优先级:指定固有路径的最高

ServletContext

功能
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,代表了当前的web应用。
就相当于全局变量,或者说是单例模式,每个实例获取的ServletContext都是一样的。

共享数据
分为添加与获取两部分:

// 添加
public class HelloServlet extends HttpServlet {
    // get和pose只是请求实现的不同方式,可以相互调用,业务逻辑都一样
    // 参数:请求、响应,然后还要抛异常
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取
        ServletContext servletContext = this.getServletContext();
        // 添加全局属性
        servletContext.setAttribute("username", "张三");
    }
}
// 获取
public class getContext extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取ServletContext元素
        ServletContext servletContext = this.getServletContext();
        Object username = servletContext.getAttribute("username");

        // 设置格式
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        // 网页打印
        PrintWriter writer = resp.getWriter();
        writer.print("名字" + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    <servlet>
        <servlet-name>getcservlet-name>
        <servlet-class>com.it.servlet.getContextservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>getcservlet-name>
        <url-pattern>/getcurl-pattern>
    servlet-mapping>

获取初始化参数

    
    <context-param>
        <param-name>urlparam-name>
        <param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
    context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

请求转发
JavaWeb笔记_第9张图片
感觉后来的都是直接用req来转发?

public class doDispatch extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        // 设置请求转发的路径, 路径是在localhost后面输入就能跳转那种
        // RequestDispatcher gp = servletContext.getRequestDispatcher("/gp");
        // 将自己的参数传递给设置好的路径,有了这个就能使用了
        // gp.forward(req, resp);

        // 也可以一步到位
        servletContext.getRequestDispatcher("/gp").forward(req, resp);
    }

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

    
    <servlet>
        <servlet-name>dispatchservlet-name>
        <servlet-class>com.it.servlet.doDispatchservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatchservlet-name>
        <url-pattern>/dpurl-pattern>
    servlet-mapping>

读取资源文件
Properties:

  • 可以在java目录下创建
  • 也可以在resource目录下创建
    两个都会被打包到targetclasses
    路径:/就是target里的子项目名文件夹
username=root12312
password=zxczxczxc
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取输入流
        InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop = new Properties();
        prop.load(resourceAsStream);
        String username = prop.getProperty("username");
        String password = prop.getProperty("password");
        PrintWriter writer = resp.getWriter();
        writer.print(username + " : " + password);
    }

HttpServletResponse

web服务器接收到客户端http的请求,会分别创建一个RequestResponse

  • 获取参数用Request
  • 传送给客户端用Response

下载文件

  1. 向浏览器输出信息,要有流
  2. 下载文件
    1. 获取文件路径
    2. 获取文件名
    3. 设置Head,让浏览器能支持下载操作
    4. 设置输入流
    5. 创建缓冲
    6. 设置输出流
    7. 将缓冲的写到输出,然后全都关闭
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 文件路径
        String path = "D:\\同步文件夹\\javaweb-02-Servlet\\response\\src\\main\\resources\\头像.jpg";
        // 2. 获取文件名称,通过获取最后一个\\的位置+1来获取文件名
        String name = path.substring(path.lastIndexOf("\\") + 1);
        // 3. 设置浏览器head, 大部分内容都是固定的
        // resp.setHeader("Content-Disposition", "attachment;filename=" + name);
        // 获取中文名的方法
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));

        // 下面就是读取文件并导出
        // 4. 创建输入流
        FileInputStream fileInputStream = new FileInputStream(path);
        // 5. 创建缓冲区
        int len=0;
        byte[] buffer = new byte[1024];
        // 6. 通过resp创建输出流, 这个应该是管通过浏览器输出吧
        ServletOutputStream outputStream = resp.getOutputStream();
        // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
        while ((len=fileInputStream.read(buffer)) > 0) {
            outputStream.write(buffer);
        }
        fileInputStream.close();
        outputStream.close();
    }

重定向
JavaWeb笔记_第10张图片

A告诉了B,B让A去找C
常见场景:登录页面

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 原理
    // 设置位置
    // resp.setHeader("Location","/down");
    // 设置状态
    // resp.setStatus(302);
    resp.sendRedirect("/down");
}

转发与重定向区别

方法 跳转与url 过滤 虚拟路径 方法位置原因
转发 req.getRequestDispatcher("").forward(req, resp) 页面会跳转,但是url不变 不会触发过滤器 不用写,/会识别成web应用地址 因为还带有参数,就相当于把参数打包再做一个带参数的请求,相当于封装了一层
重定向 resp.sendRedirect("") 页面会跳转,url也会变化 到了新的地址会触发过滤器 用写 没什么参数,不需要封装,直接跳就完了

简单的登录重定向案例



Hello World!

<%--提交路径,找到项目的路径--%> <%--pageContext.request.contextPath代表当前的项目--%>
<%--文字就直接写了--%> 用户名:
<%--password类型就会隐藏输入--%> 密码: <
<%--出现一个提交按钮--%> <
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("进入这个请求了");
    // 使用,获取参数
    String username = req.getParameter("username");
    String password = req.getParameter("password");
    System.out.println(username + " : " + password);
    // 重定向要注意路径
    resp.sendRedirect("/down");
}

HttpServletRequest

HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息;

LoginServlet

    @Override
    protected void doGet(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[] hobbies = req.getParameterValues("hobbies");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("=================");

        // 地址
        System.out.println(req.getContextPath());
        req.getRequestDispatcher("/success.jsp").forward(req, resp);
    }

index.jsp:

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


    Login


用户名:
密码:
爱好: <%--多选--%> 抽烟 喝酒 烫头

Cookie, Session

会话:打开浏览器就会创建,关闭浏览器就会重置。

状态会话:来过一次,下次来就记得了。

状态会话两种方式

  1. 服务器给客户端一个文件,下次访问时客户端出示文件,即可证明。(Cookie)
  2. 服务器自身记住客户端,下次访问时可以认出客户端。(Session)

Cookie

过程

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie

JavaWeb笔记_第11张图片

浏览器查看cookie
在Application里可以看到Cookie
JavaWeb笔记_第12张图片

相关方法

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

使用cookie

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先设置编码
    resp.setCharacterEncoding("utf-8");
    req.setCharacterEncoding("utf-8");
    PrintWriter out = resp.getWriter();
    // 服务器从客户端获取cookie,从存放在电脑本地的cookie中获取
    Cookie[] cookies = req.getCookies();

    // 本身会存在一些默认的cookie
    if (cookies != null){
        for (Cookie cookie : cookies){
            // 获取cookie属性
            if (cookie.getName().equals("Time")){
                long lastTime = Long.parseLong(cookie.getValue());
                System.out.println(lastTime);
                Date date = new Date(lastTime);
                out.write(URLDecoder.decode("时间: " + date.toGMTString(),"utf-8"));
            }
        }
    }

    // 添加cookie
    Cookie c = new Cookie("Time", URLEncoder.encode(System.currentTimeMillis()+"","utf-8"));
    // 给Cookie设置时间
    c.setMaxAge(24*60*60);
    // 服务器给客户端发送一个cookie,保存到本地, 所以是响应
    resp.addCookie(c);
}

删除cookie
应一个新的同名的来替换,然后设置立马过期,相当于删除

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 先设置编码
    resp.setCharacterEncoding("utf-8");
    req.setCharacterEncoding("utf-8");
    PrintWriter out = resp.getWriter();
    // 服务器从客户端获取cookie,从存放在电脑本地的cookie中获取
    Cookie[] cookies = req.getCookies();

    // 本身会存在一些默认的cookie
    if (cookies != null){
        for (Cookie cookie : cookies){
            // 获取cookie属性
            if (cookie.getName().equals("Time")){
                out.print(cookie.getValue());
            }
        }
    }

    // 添加cookie
    Cookie c = new Cookie("Time", System.currentTimeMillis()+"");
    // 给Cookie设置时间
    c.setMaxAge(24*60*60);
    // 服务器给客户端发送一个cookie,保存到本地, 所以是响应

    // 再加个key同名的cookie就是替换
    Cookie del = new Cookie("Time", "asdasd");
    // 立马过期,相当于删除
    del.setMaxAge(0);

    resp.addCookie(c);
    resp.addCookie(del);

}

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

cookie的限制

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

编码与解码

URLEncoder.encode("编码","utf-8")
URLDecoder.decode(cookie.getValue(),"UTF-8")

Session

过程
JavaWeb笔记_第13张图片

概念

  • 服务器会给每个浏览器创建一个Session。
  • 一个Session独占一个浏览器,只要浏览器没关闭,Session就会存在。
  • 用户登陆后,整个网站都可以访问,会通过Session来获取权限。
  • session也能注销。注销后id就没了,但立马会生成新的。

session和cookie的区别

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

使用场景

  • 保存一个登录用户的信息。
  • 购物车信息。
  • 在整个网站中经常会使用的数据,保存到session中。

使用Session

package com.kuang.servlet;

import com.kuang.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

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

        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session
        HttpSession session = req.getSession();
        //给Session中存东西
        session.setAttribute("name",new Person("秦疆",1));
        //获取Session的ID
        String sessionId = session.getId();

        //判断Session是不是新创建
        if (session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session以及在服务器中存在了,ID:"+sessionId);
        }

        //Session创建的时候做了什么事情;
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

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

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

Person person = (Person) session.getAttribute("name");

System.out.println(person.toString());

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

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


<session-config>
    
    <session-timeout>15session-timeout>
session-config>

JSP

JSP如何执行

  • 代码层面没啥问题
  • 服务器内部工作
    • tomcat中有一个work目录
    • IDEA中使用Tomcat的会在IDEA中的tomcat中产生一个work目录
  • 浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
  • JSP最终也会被转换成一个Java类,JSP本质上就是一个Servlet

内置对象

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                      //响应

输出页面前的代码
这些对象都已经准备好了,可以直接使用

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;

特点

  • java的代码会原封不动的输出。
  • 如何使HTML代码,会被转换成out.write("\r\n");这样的格式被输出到前端。

JSP基础语法和指令

表达式

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

jsp脚本片段

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

这种东西会被转义 out.println("

Sum = " + sum + "

"); %>

jsp中断继续

  <%--jsp中断--%>
  <%
    int x = 10;
  %>
  <%--<p>可以直接显示--%>
  <p>中途插入</p>
  <%
    out.println(x);
  %>
  </body>

嵌套遍历

  <%--嵌套遍历--%>
  <%
    for (int i = 0; i < 4; i++) {
  %>
  <p> 嵌套</p>
  <%
    }
  %>

jsp声明
会被编译到JSP生成java的类中。

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

    private int globalVar = 0;

    public void kuang(){
      // 这里面不能用out那些东西了
      // 因为这个会被当成编译的Java类的方法,而不是在_jspService中
      System.out.println("进入了方法狂");
    }
  %>

EL表达式
${}

注释
JSP的注释<%----%>不会在页面中显示,HTML的会。

自定义错误页面的跳转

指定单独页面的跳转
使用<%@page errorPage="error/500.jsp" %>来指定。

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

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


    Title



<%
    int x = 1/0;
%>


图片显示

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



    Title


500


设置总体的错误跳转
要在web.xml中设置,error-code指定错误类型:

    <error-page>
        <error-code>404error-code>
        <location>/error/404.jsplocation>
    error-page>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


找不到

网站头尾

页面嵌入:两种方法,include和jsp标签,区别是include是页面多合一,而jsp标签是拼接页面,本质还是三个。

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


    Title



    <%--多合一--%>
    <%@include file="/common/header.jsp"%>
    

本身

<%@include file="/common/footer.jsp"%> <%--jsp标签--%>

本身2

JSP内置对象及作用域

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


    Title


<%
    pageContext.setAttribute("name1", "jojo1");
    request.setAttribute("name2", "jojo2");
    session.setAttribute("name3", "jojo3");
    application.setAttribute("name4", "jojo4");
%>

<%
    String name1 = (String) pageContext.getAttribute("name1");
    String name2 = (String) pageContext.getAttribute("name2");
    String name3 = (String) pageContext.getAttribute("name3");
    String name4 = (String) pageContext.getAttribute("name4");
    String name5 = (String) pageContext.getAttribute("name5");
%>

取出的值为:

${name1}

${name2}

${name3}

${name4}

EL表达式:

<%--不显示--%>

${name5}

另一种方法

<%--显示null--%>

<%=name5%>

从低层到高层(作用域):
前两个是不能跨页面使用的,转发页面的话第二个有效

pageContext.setAttribute("name1","秦疆1号"); //保存的数据只在一个页面中有效
request.setAttribute("name2","秦疆2号"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","秦疆3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","秦疆4号");  //保存的数据只在服务器中有效,从打开服务器到关闭服务器

页面转发
前端只需要一句:pageContext.forward("/index.jsp")

JSP、JSTL标签、EL表达式

导包

    
    <dependency>
        <groupId>javax.servlet.jsp.jstlgroupId>
        <artifactId>jstl-apiartifactId>
        <version>1.2version>
    dependency>

    
    <dependency>
        <groupId>taglibsgroupId>
        <artifactId>standardartifactId>
        <version>1.1.2version>
    dependency>

EL表达式

  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
  • 使用EL表达式不显示null,更美观。

JSP标签

之前见过一个include,可以合并或拼接;
还有转发,转发的时候可以带上参数。

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


    Title



    
    



接受参数

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


    Title


单走一个六

名字: <%=request.getParameter("name")%> 年龄: <%=request.getParameter("age")%>

实例化类并设置数据

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


    Title



<%--声明类实例吧--%>

<%--设置类属性--%>
<%--不管是什么类型都用""包起来--%>




<%--取出值--%>
地址: 


jstl表达式

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

JavaWeb笔记_第14张图片

使用步骤

  1. 引入对应的taglib。
  2. 使用其中的方法。
  3. 在Tomcat中也要引入jstl-api-1.2.jarstandard-1.1.2.jar,可以右键打开Tomcat包的文件夹,将包放入。

报错org.apache.jasper.JasperException: 无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]
解决:在Tomcat中也要引入jstl-api-1.2.jar

if测试

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


    Title


if测试


<%--这个value有啥用啊--%>
<%--判断如果提交的用户名是管理员,则登录成功--%> <%--test如果为true,则变量isAdmin的值为true--%>

choose测试
when和带有break的case差不多。

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


    Title



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



    
        
    
    
        不及格
    




foreach测试

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


    Title


<%
    List list = new ArrayList<>();
    list.add("zs");
    list.add("ls");
    list.add("ww");
    list.add("wa");
    list.add("wb");
    list.add("wc");
    // 要在请求中添加才能用
    request.setAttribute("list", list);
%>

<%--var是抽取出来的单个对象,items是要遍历的对象--%>

    
    

第二种方法


遇到问题
IDEA重启后web框架没了,解决方法是再添加一个
JavaWeb笔记_第15张图片


MVC

三层架构
JavaWeb笔记_第16张图片

Model

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

View

  • 展示数据
  • 提供链接发起Servlet请求(就是前端页面吧)

Controller

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

流程
登录—>接收用户的登录请求—>处理用户的请求(获取用户登录的参数,username,password)---->交给业务层处理登录业务(判断用户名密码是否正确:事务)—>Dao层查询用户名和密码是否正确–>数据库


Filter

使用场景

  • 处理中文乱码
  • 验证登录

使用流程

  1. 导包
  2. 编写过滤器,实现Filter接口的方法
public class filterDemo1  implements Filter {
    // 在服务器启动的时候就初始化了,因为要对所有的请求进行判断是否过滤
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("初始化");
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        // chain的作用:
        // 1. 过滤所有的代码,在触发特定请求的时候会执行
        // 2. 处理完后,还要让过滤器继续往后走

        // 解决乱码
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=UTF-8");
        // 解决完了req和resp要继续往前走
        System.out.println("filter执行前");
        // 不写这个程序到这就结束了
        chain.doFilter(req, resp);
        System.out.println("filter执行后");
    }

    // web服务器关闭的时候(TomCat停止),会销毁
    public void destroy() {
        System.out.println("销毁过滤器");
    }
}
  1. 配置xml

<filter>
    <filter-name>filterDemo1filter-name>
    <filter-class>com.it.filter.filterDemo1filter-class>
filter>
<filter-mapping>
    <filter-name>filterDemo1filter-name>
    
    <url-pattern>/servlet/*url-pattern>
filter-mapping>

Filter做权限管理

配置文件

    
    <servlet>
        <servlet-name>loginservlet-name>
        <servlet-class>com.it.log.loginservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>loginservlet-name>
        <url-pattern>/log/loginurl-pattern>
    servlet-mapping>

    
    <servlet>
        <servlet-name>logoutservlet-name>
        <servlet-class>com.it.log.logoutservlet-class>
    servlet>
    <servlet-mapping>
        <servlet-name>logoutservlet-name>
        <url-pattern>/log/logouturl-pattern>
    servlet-mapping>

    
    <filter>
        <filter-name>filter1filter-name>
        <filter-class>com.it.filter.logFilterfilter-class>
    filter>
    <filter-mapping>
        <filter-name>filter1filter-name>
        <url-pattern>/success.jspurl-pattern>
    filter-mapping>

登录页面

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


    Title


登陆页面

<%--这个action是map的路径,傻了--%>

登录类
接受登录页面的参数,并传递给Session

public class login extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取前端的参数
        String username = req.getParameter("username");
        // 判断是否跳转
        if (username.equals("jojo")){
            // 给session传递一个参数作为证明
            req.getSession().setAttribute(UserName, req.getSession().getId());
            resp.sendRedirect("/success.jsp");
        } else {
            resp.sendRedirect("/error.jsp");
        }
    }

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

过滤器类
ServletRequest需要强制转换成HttpServletRequest

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    // 强转,这个是被包装了一层架构,少一些方法
    HttpServletRequest req = (HttpServletRequest) servletRequest;
    HttpServletResponse resp = (HttpServletResponse) servletResponse;


    // 判断是否已经登录了
    if (req.getSession().getAttribute(UserName) == null){
        // 没登陆就转到登录
        resp.sendRedirect("/login.jsp");
    }

    filterChain.doFilter(servletRequest, servletResponse);
}

登录成功页面

注销

可以做点击跳转

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


    Title


登录成功

注销

登录失败页面:

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


    Title


登录失败

返回登录页面

注销类

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 移除属性
    if (req.getSession().getAttribute(UserName) != null){
        req.getSession().removeAttribute(UserName);
    }
    resp.sendRedirect("/login.jsp");
}

JDBC复习

JavaWeb笔记_第17张图片

基础操作

固定步骤

  1. 加载驱动
  2. 连接数据库
  3. 获取执行SQL对象
  4. 编写SQL
  5. 获取结果
  6. 关闭

例子

public class TestJDBC {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url = "jdbc:mysql://localhost:3306/web";
        // 1. 加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2. 连接数据库
        Connection connection = DriverManager.getConnection(url,"root", "1234");
        // 3. 获取执行sql的对象
        Statement statement = connection.createStatement();
        // 4. 编写SQL
        String sql = "select * from users";
        // 5. 获取结果
        ResultSet resultSet = statement.executeQuery(sql);

        while (resultSet.next()){
            System.out.println("id=" + resultSet.getObject("id"));
            System.out.println("id=" + resultSet.getObject("name"));
            System.out.println("id=" + resultSet.getObject("password"));
            System.out.println("id=" + resultSet.getObject("email"));
            System.out.println("id=" + resultSet.getObject("birthday"));
        }
        // 6. 先开后关
        resultSet.close();
        statement.close();
        connection.close();
    }
}

预编译问题

public class TestJDBC2 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        String url = "jdbc:mysql://localhost:3306/web";
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, "root", "1234");
        // 预编译sql,添加占位符
        String sql = "insert into users values (?,?,?,?,?)";
        // 预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        // 给不同的占位符设置值
        preparedStatement.setInt(1,4);
        preparedStatement.setString(2,"jojo");
        preparedStatement.setString(3, "1234");
        preparedStatement.setString(4,"123@qq");
        // 注意这里的操作,外面的Date是sql类型的,里面的是java的util包里的
        preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));

        // 执行
        preparedStatement.executeUpdate();
        preparedStatement.close();
        connection.close();
    }
}

事务

回滚

public class TestJDBC3 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            // 1. 加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/web";
            connection = DriverManager.getConnection(url, "root", "1234");
            // 将自动提交事务设置为false,这样在手动提交的时候,才会被提交
            connection.setAutoCommit(false);
            statement = connection.createStatement();
        } catch (Exception e) {
            try{
                e.printStackTrace();
                // 出异常了,回滚
                connection.rollback();
            } catch (Exception e1){
                e1.printStackTrace();
            }
        } finally {
            // 最后要关闭
            try{
                connection.close();
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

你可能感兴趣的:(开发)