Java_Servlet&Jsp

The Docs of java web class

1.Servlet

1.1 servlet简介

把实现了Servlet接口的Java程序叫做,Servlet

  • Servlet就是sun公司开发动态web的一门技术。
  • Sun在这些API中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
    1. 编写一个类,实现Servlet接口;
    2. 把开发好的Java类部署到web服务器中。 把实现了Servlet接口Java程序叫做,Servlet

1.2 HelloServlet

Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServlet img

  1. 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就是Maven主工程;

    img

  2. 关于Maven父子工程的理解:

    • 父工程会显示子工程的信息
    • 子工程会继承父工程。
    • img
  3. 父工程中会有:

    1
    2
    3
    
         <modules>
             <module>servlet-01</module>
         </modules>
    

    子项目中会有:

    1
    2
    3
    4
    5
    
     <parent>
             <groupId>org.example</groupId>
             <artifactId>javaweb-servlet</artifactId>
             <version>1.0-SNAPSHOT</version>
         </parent>
    

    父项目中的jar包,子项目可以直接使用。反之,不可。

  4. 编写一个Servlet程序

    4.1、在父工程引用相关的Jar包

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    <!-- servlet -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>
    <!-- jsp -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>
    

    4.2、普通maven转web项目

    https://www.cnblogs.com/jichi/p/11356759.html

    1.编写一个普通的类 2.实现Servlet接口,这里我们直接继承HttpServlet类

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
     public class HelloServlet extends HttpServlet {
         @Override
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             System.out.println("hello servlet");
             PrintWriter writer = resp.getWriter();
             writer.println("Hello Servlet");
         }
         @Override
         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             this.doGet(req,resp);
         }
     }
    
  5. 编写Servlet的映射 为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    <!--在web.xml中注册servlet-->
    <servlet>
     <servlet-name>helloservlet</servlet-name>
     <servlet-class>com.sunyiwenlong.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--servlet请求路径-->
    <servlet-mapping>
     <servlet-name>helloservlet</servlet-name>
     <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  6. 配置tomcat 注意:配置项目发布路径就可以了

  7. 启动测试

1.3 Servlet原理

img

1.4 Mapping问题

  1. 1、一个Servlet可以指定一个映射路径

    1
    2
    3
    4
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    

    2、一个Servlet可以指定多个映射路径

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello4</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello5</url-pattern>
    </servlet-mapping>
    

    3、一个Servlet可以指定通用映射路径

    1
    2
    3
    4
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
    

    4、默认请求路径

    1
    2
    3
    4
    
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

    5、指定一些后缀或者前缀等等…

    1
    2
    3
    4
    5
    
    <!-- 注意,*前面不能加项目映射的路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.demo</url-pattern>
    </servlet-mapping>
    

    6、优先级问题 指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <!--404-->
    <servlet>
        <servlet-name>error</servlet-name>
        <servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>error</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

1.5 ServletContext

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

  1. 共享数据:在这个Servlet中保存的数据,可以在另一个Servlet中拿到 img

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    public class HelloServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         // this.getInitParameter(); 获取初始化参数(web.xml文件中的初始化参数)
         // this.getServletConfig(); 获取servlet的配置(web.xml文件中的配置)
         // this.getServletContext(); 获取servlet上下文
         ServletContext context = this.getServletContext();
         String username = "小明";
         context.setAttribute("username",username);// 将一个数据保存在了ServletContext中
     }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    public class GetServlet 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");
         resp.getWriter().println("名字"+username);
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req,resp);
     }
    }
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    // web.xml文件
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
          xmlns="http://java.sun.com/xml/ns/j2ee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <servlet>
     <servlet-name>helloservlet1</servlet-name>
     <servlet-class>com.sunyiwenlong.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
     <servlet-name>helloservlet1</servlet-name>
     <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet>
     <servlet-name>getservlet</servlet-name>
     <servlet-class>com.sunyiwenlong.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
     <servlet-name>getservlet</servlet-name>
     <url-pattern>/getc</url-pattern>
    </servlet-mapping>
    </web-app>
    

    测试访问结果:

    img

  2. 获取初始化参数

    1
    2
    3
    4
    5
    6
    
    // web.xml文件
    <!--配置一些web应用一些初始化参数-->
    <context-param>
     <param-name>url</param-name>
     <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    public class ServletDemo03 extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         String url = this.getInitParameter("url");
         resp.getWriter().println(url);
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req, resp);
     }
    }
    
  3. 请求转发

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    // web.xml文件
    // 请求sd4
    <servlet>
     <servlet-name>gp</servlet-name>
     <servlet-class>com.sunyiwenlong.servlet.ServletDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
     <servlet-name>gp</servlet-name>
     <url-pattern>/gp</url-pattern>
    </servlet-mapping>
    <servlet>
     <servlet-name>sd4</servlet-name>
     <servlet-class>com.sunyiwenlong.servlet.ServletDemo04</servlet-class>
    </servlet>
    <servlet-mapping>
     <servlet-name>sd4</servlet-name>
     <url-pattern>/sd4</url-pattern>
    </servlet-mapping>
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    // 请求/sd4找到ServletDemo04,ServletDemo04进行请求转发到/gp,到/gp的页面
    // (浏览器路径是sd4的路径,页面拿到的是/gp的数据)
    public class ServletDemo04 extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         ServletContext context = this.getServletContext();
         System.out.println("进入了demo04");
         // RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");// 转发的路径
         // requestDispatcher.forward(req,resp);// 调用forward请求转发
         context.getRequestDispatcher("/gp").forward(req,resp);
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req, resp);
     }
    }
    
  4. 读取资源文件 Properties

  • 在java目录下新建properties
  • 在resources目录下新建properties发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath。

思路:需要一个文件流

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/CLASSES/db.properties");
        Properties properties = new Properties();
        properties.load(stream);
        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 {
        this.doGet(req, resp);
    }
}

img

1.6 HttpServletResponse

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

  • 如果要获取客户端请求过来的参数:找HttpServletRequest
  • 如果要给客户端响应一些信息:找HttpServletResponse
  1. 负责向浏览器发送数据的方法

    1
    2
    
    public ServletOutputStream getOutputStream() throws IOException;
    public PrintWriter getWriter() throws IOException;
    
  2. 响应的状态码

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    public static final int SC_CONTINUE = 100;
     /**
      * Status code (200) indicating the request succeeded normally.
      */
     public static final int SC_OK = 200;
     /**
      * Status code (302) indicating that the resource has temporarily
      * moved to another location, but that future references should
      * still use the original URI to access the resource.
      *
      * This definition is being retained for backwards compatibility.
      * SC_FOUND is now the preferred definition.
      */
     public static final int SC_MOVED_TEMPORARILY = 302;
     /**
     * Status code (302) indicating that the resource reside
     * temporarily under a different URI. Since the redirection might
     * be altered on occasion, the client should continue to use the
     * Request-URI for future requests.(HTTP/1.1) To represent the
     * status code (302), it is recommended to use this variable.
     */
     public static final int SC_FOUND = 302;
     /**
      * Status code (304) indicating that a conditional GET operation
      * found that the resource was available and not modified.
      */
     public static final int SC_NOT_MODIFIED = 304;
     /**
      * Status code (404) indicating that the requested resource is not
      * available.
      */
     public static final int SC_NOT_FOUND = 404;
     /**
      * Status code (500) indicating an error inside the HTTP server
      * which prevented it from fulfilling the request.
      */
     public static final int SC_INTERNAL_SERVER_ERROR = 500;
     /**
      * Status code (502) indicating that the HTTP server received an
      * invalid response from a server it consulted when acting as a
      * proxy or gateway.
      */
     public static final int SC_BAD_GATEWAY = 502;
     // ...
    
1
常见应用
  1. 向浏览器输出消息

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    public class HelloWorld extends HttpServlet {
        @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);
        }
    }
    
  2. 下载文件

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
    public class FileServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         // 1.要获取下载文件的路径
         String realPath = "E:\\dev\\StudyProjects\\javaweb-servlet\\response\\src\\main\\resources\\大乔.jpg";
         // 2.下载的文件名是啥?
         String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
         // 3.设置想办法让浏览器能够支持下载我们需要的东西
         resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(filename,"utf-8"));
         // 4.获取下载文件的输入流
         FileInputStream in = new FileInputStream(realPath);
         // 5.创建缓冲区
         int len = 0;
         byte[] buffer = new byte[1024];// 每次读取的长度
         // 6.获取OutputStream对象
         ServletOutputStream out = resp.getOutputStream();
         // 7.将FileOutputStream流写入到bufer缓冲区
         while ((len = in.read(buffer))>0){// 每次读取的长度大于0的情况下,就写出去
             out.write(buffer,0,len);// 写出字节,从0写到len
         }
         // 8.使用OutputStream将缓冲区中的数据输出到客户端!
         in.close();
         out.close();
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req, resp);
     }
    }
    
  3. 验证码功能

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    
    public class ImageServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         // 让浏览器3秒刷新一次
         resp.setHeader("refresh", "3");
         // 在内存中创建一个图片
         BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);// 宽、高、颜色
         // 得到图片
         Graphics2D g = (Graphics2D) image.getGraphics();// 得到一只2D的笔
         // 设置图片的背景颜色
         g.setColor(Color.white);
         g.fillRect(0, 0, 80, 20);// 填充颜色
         // 换个背景颜色
         g.setColor(Color.BLUE);
         // 设置字体样式:粗体,20
         g.setFont(new Font(null,Font.BOLD,20));
         // 画一个字符串(给图片写数据)
         g.drawString(makeNum(),0,20);
         // 告诉浏览器,这个请求用图片的方式打开
         resp.setContentType("image/jpeg");
         // 网站存在缓存,不让浏览器缓存
         resp.setDateHeader("expires",-1);
         resp.setHeader("Cache-Control","no-cache");
         resp.setHeader("Pragma","no-cache");
         // 把图片写给浏览器
         boolean write = ImageIO.write(image, "jpg",resp.getOutputStream());
     }
     // 生成随机数
     private String makeNum() {
         Random random = new Random();
         String num = random.nextInt(9999999) + "";// 随机数,最大七位,[0,9999999)
         StringBuffer sb = new StringBuffer();
         for (int i = 0; i < 7 - num.length(); i++) {// 不足七位,则添加0
             sb.append("0");
         }
         num = sb.toString()+num;// 不足七位,在随机数前面添加0
         return num;
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req, resp);
     }
    }
    
  4. 实现请求重定向

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    public class RedirectServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         /*resp.setHeader("Location","/response_war/image");
         resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);*/
         resp.sendRedirect("/response_war/image");// 重定向相当于上面两行代码
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doGet(req, resp);
     }
    }
    

5、转发与重定向

  • 转发
    • 客户端浏览器的地址栏没有变化
    • 服务端内部转发
    • 刷新会重新提交数据
    • 会保存请求域中数据
  • 重定向
    • 客户端浏览器的地址栏有变化
    • 客户端重新请求
    • 刷新不会重新提交数据
    • 不会保存请求域中数据

转发流程

img

实现代码:

1
request.getRequestDispatcher("/地址").forward(request, response);

重定向流程

img

实现代码

1
response.sendRedirect("/地址");

1.7 HttpServletRequest

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

  1. 获取前端传递的参数 img

    1
    2
    3
    4
    5
    
    //获取参数
    request.getParameter("p1");
    request.getParameterValues("p2");
    //设置request编码为UTF-8
    request.setCharacterEncoding("UTF-8");
    
  2. 请求转发 前端:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
     <title>首页</title>
    </head>
    <body>
    <form action="${pageContext.request.contextPath}/login" method="post">
     用户名:<input type="text" name="username"><br>
     密码:<input type="password" name="password"><br>
     爱好:
     <input type="checkbox" name="hobbys" value="代码"> 代码
     <input type="checkbox" name="hobbys" value="唱歌"> 唱歌
     <input type="checkbox" name="hobbys" value="女孩"> 女孩
     <input type="checkbox" name="hobbys" value="电影"> 电影
     <br>
     <input type="submit" name="提交">
    </form>
    </body>
    </html>
    

    后端:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    public class LoginServlet extends HttpServlet {
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         this.doPost(req, resp);
     }
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         // 处理请求中文乱码(后期可以使用过滤器来解决)
         req.setCharacterEncoding("utf-8");
         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));
         // 这里的 / 代表当前的web应用,所以不需要再加上/request_war这个上下文路径了,否则会出现404错误
         req.getRequestDispatcher("/success.jsp").forward(req,resp);
     }
    }
    

web.xml img

面试题:请你聊聊重定向和转发的区别? 相同点:页面都会实现跳转 不同点:

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

2.jsp

2.1 什么是jsp

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

  • 写jsp就像在写html
  • 区别:
    • html只给用户提供静态的数据
    • jsp页面中可以嵌入Java代码,为用户提供动态数据

2.2 jsp原理

思路:jsp是怎样执行的?

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

我电脑上的地址:

1
C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2

发现页面会被转换成为一个Java类! img

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问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)
  1. 判断请求的方式

  2. 内置一些对象(9个)

    1
    2
    3
    4
    5
    6
    7
    8
    
    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. 输出页面前增加的代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    response.setContentType("text/html;charset=UTF-8");// 设置响应的页面类型
    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页面中直接使用

  5. 原理图 img

在JSP页面中; 只要是JAVA代码就会原封不动的输出; 如果是HTML代码,就会被转换为:

1
2
out.write("<html>\r\n");
out.write("<head>\r\n");

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

2.3 JSP基础语法

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

  1. jsp表达式

    1
    2
    3
    4
    5
    
    <%--jsp表达式
    作用:用来将程序的输出,输出到客户端
    <%= 变量或表达式%>
    --%>
    <%= new java.util.Date() %>
    
  2. jsp脚本片段

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    <%--jsp脚本片段--%>
    <%
     int sum = 0;
     for (int i = 0; i < 100; i++) {
       sum+=i;
     }
     out.print("<h1>sum="+sum+"</h1>");
    %>
    //--------------------------
    <%--EL表达式:${变量} --%>
    <%
     for (int i = 0; i < 3; i++) {
    %>
    <h1>Hello World! ${i}</h1>
    <%
     }
    %>
    
  3. jsp声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <%!
    static {
     System.out.println("loading Servlet!");
    }
    private int globalVar =0;
    public void hello(){
     System.out.println("进入了该方法!");
    }
    %>
    

JSP声明:会被编译到jsp生成java的类中! 其他的,就会被生成到_jspService方法中! 在jsp,嵌入Java代码即可!

在JSP,嵌入Java代码即可!

1
2
3
4
<%%>
<%=%>
<%!%>
<%--注释--%>

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

2.4 jsp指令

  1. 定制错误页面

    1
    
    <%--定制错误页面--%><%@ page errorPage="error/500.jsp" %>
    

    或者在web.xml定制全局的错误页面 img

  2. 包含头部和尾部 img

2.5 九大内置对象

  • PageContext 存东西
  • Request 存东西
  • Response
  • Session 存东西
  • Application(ServletContext) 存东西
  • Config(ServletConfig)
  • out
  • page
  • exception
1
2
3
4
5
存东西的区别
pageContext.setAttribute("name1","张三1");// 保存的数据只在一个页面中有效
request.setAttribute("name2","张三2");// 保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","张三3");// 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","张三4");// 保存的数据只在服务器中有效,从打开服务器到关闭服务器

img

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

2.6 jsp标签、JSTL标签、EL表达式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- JSTL表达式的依赖 -->
<dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>jstl-api</artifactId>
    <version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>

JSP标签:JSP自带比较简单的标签。

jsp:forward

​ jsp:param

JSTL表达式:扩展很多自定义标签。

EL表达式${ }

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

JSTL表达式

引入库:

https://www.runoob.com/jsp/jsp-jstl.html

JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。

img

c:if

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<head>
    <title>Title</title>
</head>
<body>
    <h3>if测试</h3>
    <hr>
    <form action="coreif.jsp" method="get">
    <%--
        EL表达式获取表单中的数据
        ${param.参数名}
    --%>
        <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:if>
    <%--自闭合标签--%>
    <c:out value="${isAdmin}"/>
</body>

c:choose c:when

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<body>
<%--定义一个变量score,值为85--%>
<c:set var="score" value="55"/>
<c:choose>
    <c:when test="${score>=90}">
    你的成绩为优秀
    </c:when>
    <c:when test="${score>=80}">
    你的成绩为一般
    </c:when>
    <c:when test="${score>=70}">
    你的成绩为良好
    </c:when>
    <c:when test="${score<=60}">
    你的成绩为不及格
    </c:when>
</c:choose>
</body>

c:forEach

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%
    List<String> nameLists = new ArrayList<>();
    nameLists.add("张三");
    nameLists.add("李四");
    nameLists.add("王五");
    nameLists.add("赵六");
    nameLists.add("田六");
    request.setAttribute("list",nameLists);
%>
<%--
var , 每一次遍历出来的变量
items, 要遍历的对象
begin, 哪里开始
end, 到哪里
step, 步长
--%>
<c:forEach var="name" items="${list}">
    <c:out value="${name}"/> <br>
</c:forEach>
<hr>
<c:forEach var="name" items="${list}" begin="1" end="3" step="1" >
    <c:out value="${name}"/> <br>
</c:forEach>

Written by VastCosmic & Post in 泠境
Explore the Infinity Cosmos.
Built with Hugo
Designed By VastCosmic with Hugo Theme Stack