Java之JavaWeb

JavaWeb

基本概念

web开发:

  • web ---- 网页
  • 静态web
    • html css 提供给所有人看的 数据始终不会发生变化
  • 动态web
    • 技术栈 servlet/jsp asp php
  • java中动态web资源开发技术统称为javaWeb

静态web

服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息

web服务器:
IIS windows自带
tomcat

Tomcat

启动关闭 bin/startup.sh shutdown.sh

HTTP:
百度:

Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 36.152.44.96:443

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
  1. 请求行
    • 请求方式:GET POST HEAD DELETE
      • get:请求能够携带的参数比较少,大小有限制,会在url地址栏显示数据内容,不安全但是高效
      • post:请求能够携带的参数无限制,大小没有限制,不会在url地址显示数据内容,安全,但不高效
  2. 消息头
Accept: 告诉浏览器 支持的数据类型
Accept-Encoding: 支持哪种编码
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器 请求完成是断开还是保持连接

HTTP响应
200 请求响应成功
3xx 请求重定向
4xx 找不到资源 404
5xx 服务器代码错误 500 502网关错误

常见面试题
当浏览器地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么

Maven项目架构管理工具

阿里云镜像加速
setting.xml

pom.xml
jar:java应用
war:javaweb应用
properties 配置
build 项目构建用的东西

Servlet

什么是Servlet
  • Servlet是开发动态web的一门技术
  • Servlet就是一个接口,Servlet只需要编写一个类实现Servlet,把开发好的java类部署到web服务器中
helloServlet

Servelt接口有两个默认的实现类 HttpServlet

  1. 构建一个Maven项目,删掉里面的src目录,以后在这个项目里建立moudel,这个空的工程就是maven主工程
  2. 关于Maven父子工程的理解:
    父项目中会有
    <modules>
        <module>servlet-01</module>
    </modules>
    

父项目中的java子项目可以直接使用

  1. Maven环境优化
    1. 修改web.xml为最新的
    2. 将maven结构搭建完整
  2. 编写servlet ,实现Servlet,或者继承HttpServlet
public class HelloServlet extends HttpServlet {

    //由于get或者post只是请求实现的不同的方式 可以相互调用 业务逻辑都一样
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter writer = resp.getWriter();
        writer.print("Hello,Servlet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 编写Servlet的映射
    为什么需要映射:我们写的是Java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给一个浏览器能访问的路径
<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_3_1.xsd"
         version="3.1"
         metadata-complete="true">

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
</web-app>
  1. 配置Tomcat
    注意:配置项目发布的路径就可以了
  2. 启动测试
Servlet原理

Servlet是由Web服务器调用,web服务在收到浏览器请求之后会:
在这里插入图片描述

Mapping问题
  1. 一个Servlet可以指定一个映射路径
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
  1. 一个Servlet可以指定多个映射路径
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet1</url-pattern>
    </servlet-mapping>
  1. 一个Servlet可以指定通用映射路径
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet/*</url-pattern>
    </servlet-mapping>
  1. 默认请求路径
	可以替换掉默认首页
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
  1. 指定一些后缀或者前缀等等
	可以自定义后缀实现请求映射
	注意:*前面不能加项目映射的路径
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  1. 优先级问题
    指定了固有的映射优先级最高,找不到就会找默认请求路径
	默认请求路径是ErrorServlet,当访问/helloServlet的时候,页面跳转HelloServlet,但是其它时候就跳转ErrorServlet
	<servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/helloServlet</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>ErrorServlet</servlet-name>
        <servlet-class>com.wang.servlet.ErrorServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>ErrorServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
ServletContext

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

  • 共享数据
    • 在这个Servlet中保存的数据可以在其它Servlet中使用
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Hello");
//        this.getInitParameter(); 初始化参数
//        this.getServletConfig(); Servlet配置
//        this.getServletContext(); Servlet上下文
        ServletContext context = this.getServletContext();
        String username = "username";
        context.setAttribute("username", username); //将一个数据保存在ServletCOntext中 kv对
    }

    @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 context = this.getServletContext();
        // HelloServlet中的username可以在GetServelt中获取到(需要先加载HelloServlet)
        String username = (String) context.getAttribute("username");
        System.out.println(this.getClass().getName() + ":" + username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    <servlet>
        <servlet-name>Hello</servlet-name>
        <servlet-class>com.wang.servlet.HelloServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>Hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>GetContext</servlet-name>
        <servlet-class>com.wang.servlet.GetServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>GetContext</servlet-name>
        <url-pattern>/getContext</url-pattern>
    </servlet-mapping>

获取初始化参数

    <!--    配置一些web应用初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://aliyun:3306/mybatis</param-value>
    </context-param>
    <servlet>
        <servlet-name>ServletDemo03</servlet-name>
        <servlet-class>com.wang.servlet.ServletDemo03</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>ServletDemo03</servlet-name>
        <url-pattern>/servletDemo03</url-pattern>
    </servlet-mapping>
public class ServletDemo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        System.out.println(url); //jdbc:mysql://aliyun:3306/mybatis
    }

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

请求转发(请求转发的时候不跳转url 只是页面跳转)

public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/servletDemo03");  //转发的请求路径
        requestDispatcher.forward(req, resp); //会进入servletDemo03界面 但是url还是在servletDemo04 
    }

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

在这里插入图片描述

读取资源文件
Properties

  • 在java目录下新建properties
  • 在resources目录下新建properties
    发现:都被打包到了同一路径下,classes,我们俗称为这个路径为classPath
    在这里插入图片描述
    如果将properties放在java目录下,资源可能会导出失败,在pom.xml中配置
    <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>

默认不需要配置resources目录

思路:需要一个文件流

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(is);
        String user = (String) properties.get("user");
        System.out.println(user);
    }

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

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

  1. 获取前端传递的参数
    在这里插入图片描述
  2. 请求转发
public class LoginServlet extends HttpServlet {
    @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("hobby");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
		// 请求转发
        req.getRequestDispatcher("/success.jsp").forward(req, resp);
    }

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

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 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);

常见应用:

  1. 向浏览器输出信息
  2. 下载文件
    1. 获取下载文件的路径
    2. 下载的文件名
    3. 设置想办法让浏览器支持下载我们需要的东西
    4. 获取下载文件的输入流
    5. 创建缓冲区
    6. 获取OutputStream对象
    7. 将FileInputStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
    8. 关闭资源
public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        1. 获取下载文件的路径
        String realPath = this.getServletContext().getRealPath("/1.jpg");
        System.out.println("文件路径:" + realPath);
//        2. 下载的文件名
        String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
//        3. 设置想办法让浏览器支持下载我们需要的东西
        resp.setHeader("Content-disposition", "attachment;filename" + fileName);
//        4. 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
//        5. 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
//        6. 获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
//        7. 将FileInPutStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
        while ((len = in.read(buffer)) > 0) {
            out.write(buffer, 0, len);
        }
//        8. 关闭资源
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 验证码
public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 如何让浏览器五秒自动刷新一次
        resp.setHeader("refresh", "5");

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

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

        //把图片写给浏览器
        ImageIO.write(image, "jpg", resp.getOutputStream());
    }

    //生成随机数
    private String makeNum() {
        Random random = new Random();
        String num = String.valueOf(random.nextInt(9999999));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7 - num.length(); i++) {
            sb.append("0");
        }
        num = sb.toString() + num;
        return num;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  1. 实现重定向
    一个web资源收到客户端请求后,会通知客户端去访问另外一个web资源,这个过程叫重定向
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /*
        重定向等价于这两步
        resp.setHeader("Location", "/image");
        resp.setStatus(HttpServletResponse.SC_FOUND);
         */
        resp.sendRedirect("/image"); //重定向

    }

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

重定向和转发的区别

  • 相同点:页面跳转
  • 不同点:
    • 转发 url不变 307
    • 重定向 url跳转 302
public class RequestTest extends HttpServlet {
    @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("/success.jsp");
    }

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

<html>
<body>
<h2>Hello World!</h2>

<%-- 这里提交的路径需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath} 当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名: <input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit">
</form>
</body>
</html>


    <servlet>
        <servlet-name>request</servlet-name>
        <servlet-class>com.wang.servlet.RequestTest</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>request</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

Cookie Session

cookie

  • 客户端技术(响应请求)
    session
  • 服务器技术,利用这个技术可以保存用户的会话信息,我们可以把信息或者数据放在session中

常见场景:网站登录之后下次不用登录,第二次访问自动登录

Cookie
  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
 Cookie[] cookies = req.getCookies(); //获得Cookie
 cookie.getName();  //获得Cookie的key
 cookie.getValue(); //获得Cookie的value
 Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis())); //新建一个cookie
 cookie.setMaxAge(24 * 60 * 60); //设置cookie有效期
 resp.addCookie(cookie);

public class CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        PrintWriter out = resp.getWriter();

        // cookie 服务端从客户端获取
        Cookie[] cookies = req.getCookies();

        if (cookies != null) {
            out.write("上次访问的时间是");
            for (int i = 0; i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("lastLoginTime")) {
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }
        } else {
            out.write("这是你第一次访问本站");
        }

        //服务器给客户端响应一个cookie
        Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis()));
        cookie.setMaxAge(24 * 60 * 60);
        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 一个Cookie只能保存一个信息 key-value
  • 一个web站点可以给浏览器发送多个cookie,300个cookie大概是浏览器上限,每个站点最多存放20个
  • cookie大小有限制,4Kb

删除Cookie:

  • 不设置有效期,关闭浏览器自动失效
  • 设置有效期时间为0
// 网络编程解决乱码
String encode = URLEncoder.encode("我是中文", "utf-8");
String decode = URLDecoder.decode(encode, "utf-8");
Session

什么是session

  • 服务器会给每一个用户(浏览器)创建一个Session对象
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后,整个网站都可以访问
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", "nameTest");
        session.getAttribute("name");
        // 手动注销
        session.removeAttribute("name");

        //获得session的id
        String id = session.getId();

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

        //session在创建的时候做了什么
//        Cookie cookie = new Cookie("JSESSIONID", id);
//        resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    <!--  设置session默认的失效时间 15分钟-->
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

使用场景:

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

Session和Cookie的区别:

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

JSP

什么是JSP

Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态web技术
最大的特点:

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

思路:JSP是怎么执行的

  • 服务器内部:
    tomcat中有一个work目录
    IDEA中使用Tomcat的会在IDEA中生成一个work目录(工作空间 仍然依托于自己的tomcat)
/Users/wangyinghao/Library/Caches/JetBrains/IntelliJIdea2020.1/tomcat/Unnamed_kuangshen-javaweb/work/Catalina/localhost/ROOT/org/apache/jsp

在这里插入图片描述
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
JSP最终也会被转换成一个Java类
JSP本质就是一个Servlet

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.22
 * Generated at: 2020-05-31 03:39:28 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  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 static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  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 java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  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() {
  }
//JspService
  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

//request 请求 response 响应
    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        return;
      }
    }

// 内置对象
    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
    javax.servlet.jsp.JspWriter _jspx_out = null;
    javax.servlet.jsp.PageContext _jspx_page_context = null;


    try {
    // 输出页面前增加的代码
      response.setContentType("text/html"); //设置响应的页面类型 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;
// 以上的这些对象可以在JSP页面中直接使用
// ${pageContext}
      out.write("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\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>\r\n");

JSP基础语法

<html>
<body>
<h2>Hello World!</h2>


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

<hr/>

<%--脚本片段--%>
<%
    int sum = 0;
    for (int i = 0; i < 100; i++) {
        sum += i;
    }
    out.println("<h1> Sum=" + sum + "</h1>");
%>

<%--代码中嵌入html--%>
<%
    for (int i = 0; i < 5; i++) {
%>
<h1>Hello,world  <%=i%></h1>
<%
    }
%>

<%--EL表达式  ${i}--%>

<%--JSP声明--%>
<%--会被编译到JSP生成Java类的类中 而不是_jspService中--%>
<%!
   static {
       System.out.println("Loading servlet");
   }
   private int globalVar = 0;
   public void test(){
       System.out.println("test");
   }
%>
</body>
</html>
9大内置对象
  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application ServletContext 存东西
  • config ServletConfig
  • out
  • page
  • exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--内置对象--%>
<%
    pageContext.setAttribute("name1", "name1"); //保存的数据只在一个页面有效
    request.setAttribute("name2", "name2"); //保存的数据只在一次请求中有效 请求转发会携带这个数据
    session.setAttribute("name3", "name3"); // 保存的数据只在一次会话中有效 从打开浏览器到关闭浏览器
    application.setAttribute("name4", "name4"); //保存的数据在服务器中有效 从打开服务器到关闭服务器
%>

<%
    // 通过pageContext取,我们通过寻找的方式
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    // pageContext有个类似JVM的双亲委派机制的特性 从底层到高层(作用域) page-->request-->session-->application

// pageContext.setAttribute() scope为作用域 也可以提升pageContext的作用域
public void setAttribute(String name, Object attribute, int scope) {
        switch(scope) {
        case 1:
            this.mPage.put(name, attribute);
            break;
        case 2:
            this.mRequest.put(name, attribute);
            break;
        case 3:
            this.mSession.put(name, attribute);
            break;
        case 4:
            this.mApp.put(name, attribute);
            break;
        default:
            throw new IllegalArgumentException("Bad scope " + scope);
        }
%>

<%--通过el表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>

request:客户端向服务器发送请求,产生的数据,用户看完就没用的,比如:用户看新闻
session:客户端向服务器发送请求,产生的数据用户用完一会还会用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完其他用户还可能使用,比如:聊天数据

JSP标签 JSTL标签 EL表达式

EL表达式: ${}
  • 获取数据
  • 执行运算
  • 获取web开发的常用对象
JSP标签
<jsp:forward page="jsptag2.jsp">
    <jsp:param name="name" value="nameTest"/>
    <jsp:param name="age" value="ageTest"/>
</jsp:forward>

<%--取出参数--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
JSTL标签

JSTL标签库的使用就是为了弥补HTML标签的不足:自定义了许多标签,功能和java一样

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入JSTL核心库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<hr/>

<form action="coreif.jsp" method="get">
    <%--    EL表达式获取表单中的数据--%>
    <input type="text" name="username" value="${param.username}">
    <input type="submit" value="登录">
</form>

<%--判断如果提交的用户名是管理员 则登录成功--%>
<c:if test="${param.username == 'admin'}" var="isAdmin">
    <c:out value="管理员欢迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>

<%
    ArrayList<String> people = new ArrayList<>();
    people.add(0,"张三");
    people.add(1,"李四");
    request.setAttribute("list",people);
%>

<c:forEach var="people" items="${list}">
    <c:out value="${people}"></c:out><br>
</c:forEach>

</body>
</html>

JavaBean

实例类
JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法
    一般用来和数据库的字段做映射
    ORM:对象关系映射
  • 表–>类
  • 字段–>属性
  • 行记录–>对象
<%@ page import="com.wang.pojo.People" %><%--
  Created by IntelliJ IDEA.
  User: wangyinghao
  Date: 2020/5/31
  Time: 5:13 下午
  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>

<%
//    People people = new People();
//    people.setId(1);
//    people.setAddress("上海");
//    people.setAge(10);
//    people.setName("wyh");
%>
<jsp:useBean id="people" class="com.wang.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="上海"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="10"/>
<jsp:setProperty name="people" property="name" value="wyh"/>

姓名:<jsp:getProperty name="people" property="name"/>

</body>
</html>

MVC三层架构

在这里插入图片描述
Model:

  • 业务处理:业务逻辑 Service
  • 数据持久层:CRUD Dao
    View
  • 展示数据
  • 提供链接发起Servlet请求
    Controller
  • 接收用户的请求:req请求 session信息…
  • 交给业务层处理对应的代码
  • 控制视图的跳转
登录-->接收用户的登录请求-->处理用户的请求(获取用户登录的参数,username pwd)-->交给业务层处理登录业务(判断用户名密码是否正确:事务)-->Dao层查询用户名和密码是否正确-->数据库

Filter

过滤器,用来处理网站的数据
在这里插入图片描述

public class CharacterEncodingFilter implements Filter {

    //服务器启动的时候 init就已经初始化 随时等待监听
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init");
    }

    //Chain 链
    // 过滤所有的代码 在过滤特定请求的时候都会执行 web.xml配置
    // 必须要让过滤器继续执行  filterChain.doFilter(servletRequest, servletResponse);
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html;charset=UTF-8");
        System.out.println("doFilter执行前");
        filterChain.doFilter(servletRequest, servletResponse); //让我们的请求继续走 如果不写程序就到这里被拦截停止
        System.out.println("doFilter执行后");
    }

    //web服务器关闭的时候销毁
    public void destroy() {
        System.out.println("destroy");
    }
}
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>com.wang.filter.CharacterEncodingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <!--        只要是/下的任何请求都会经过这个过滤器-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章