Servlet

Servlet是什么?

其实就是一个 Java 程序,运行在 web 服务器上,用于接受请求和响应,客户端得 http 请求。更多的是配合动态资源来做,当然静态资源也需要使用 servlet。

第一个 Servlet 程序

  1. 写一个 web 工程,要有一个服务器
  2. 运行 web 工程
    1. 新键一个类,实现 servlet 接口
    2. 配置 servlet ,告诉服务器我们的应用有这么个 servlet
 <!--向tomcat报告这个应用里面有这个servlet,名字叫做HelloServlet,具体路径是servlet.HelloServlet-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>servlet.HelloServlet</servlet-class>
    </servlet>

    <!--注册servlet的映射,url-pattern:在地址栏上的path-->
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

servlet 执行过程

在这里插入图片描述

servlet 的通用写法

Servlet(接口)
|
|
GenericServlet(抽象类)
|
|
HttpServlet(抽象类)

  1. 定义一个类继承 HttpServlet,复写 doGet 和 doPost 方法
public class HelloServlet02 extends HttpServlet {
//    @Override
//    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        System.out.println("HelloServlet02...");
//    }

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doGet(req, resp);
            System.out.println("get");
        }

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

Servlet 的生命周期

  • 生命周期方法
  • init() 方法
/**
     * 1.
     * 在创建该servlet的实例时,调用该方法
     * 默认情况下是初次访问该servlet,才会创建实例
     * 一个servlet只会初始化一次,init方法只会执行一次
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("HelloServlet03 初始化...");
    }
  • service() 方法
/**
     * 2.
     * 只要客户端来了一个请求,那么就执行这个方法
     * 该方法可以被执行很多次,一次请求,对应一次service方法的执行
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("helloServlet03 service方法执行...");
    }
  • destory() 方法
/**
     * 3.
     * servlet销毁的时候,就会执行该方法
     *   1. 该项目从tomcat里面移除
     *   2. 正常关闭tomcat
     */
    @Override
    public void destroy() {

    }

让 servlet 创建实例的时机提前

  1. 默认情况下,只有在初次访问 servlet 的时候才会执行 init() 方法。有时候,我们可能需要在这个方法里执行一些初始化工作,甚至是一些比较耗时的逻辑。
  2. 这个时候,初次访问可能会在 init() 方法中逗留太久的时间,那么有没有方法可以让这个初始化时机提前一点呢?
  3. 配置的时候,使用 load-on-startup 元素指定,给定的数字越小,启动时机就越早,从 2 开始即可。
 <servlet>
        <servlet-name>HelloServlet04</servlet-name>
        <servlet-class>HelloServlet.HelloServlet04</servlet-class>
        <!--让 servlet 创建实例的时机提前-->
        <load-on-startup>2</load-on-startup>
    </servlet>

每个 servlet 都有一个 ServletConfig

  • servlet 的配置对象,通过这个对象,可以获取 servlet 在配置的时候的一些信息或者具体的某一写参数
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.得到servlet配置对象
        javax.servlet.ServletConfig config = getServletConfig();
        //2.获取servlet的名称
        String servletName = config.getServletName();
        System.out.println(servletName);
        //可以获取具体的参数
        String initParameter = config.getInitParameter("address");
        System.out.println(initParameter);
        //获取所有参数的名称
        List<String> list = (List<String>) config.getInitParameterNames();
    }

 <servlet>
        <servlet-name>ServletConfig</servlet-name>
        <servlet-class>HelloServlet.ServletConfig</servlet-class>
        <!--添加初始化参数-->
        <init-param>
            <param-name>address</param-name>
            <param-value>北京...</param-value>
        </init-param>
    </servlet>

为什么需要有 ServletConfig ?

  1. 未来我们自己开发的一些应用使用了一些技术或者一些代码,我们不会,但是有人写出来了,它的代码放置在了自己的 servlet 类里面。
  2. 刚好这个 servlet 里面需要一个数字或者变量值,但这个值不是固定的,所以要求使用到这个 servlet 的公司,在注册 servlet 的时候,必须要在 web.xml 里面,生命 init-parameter。

servlet 配置方式

  1. 路径配置:以 / 开始
  2. 路径匹配:前半段匹配,以 / 开始,但是以 * 结束
  3. 以扩展名匹配:没有 / ,以 * 开始

整个应用只有一个 ServletContext

  • servlet 上下文
    每一个 web 工程都只有一个 ServletContext 对象。就是不管在哪一个 servlet 里面,获取到的这个类的对象都是同一个。

作用

  1. 可以获取全局配置参数;获取全局参数
  2. 获取web应用中的资源
    方法一:
public class ServletContext2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = getServletContext();
        //获取给定的文件在服务器上面的绝对路径
        //servletContext.getRealPath("") 这里得到的是项目在tomcat里面的根目录
        String path = servletContext.getRealPath("file/config.properties");
        //1.创建属性对象
        Properties properties = new Properties();
        //2.指定载入数据源
        InputStream is = new FileInputStream(path);
        properties.load(is);
        //3.获取address属性的值
        String address = properties.getProperty("address");
        System.out.println(address);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

方法二:

public class ServletContext2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取ServletContext对象
        ServletContext servletContext = getServletContext();
        //获取web工程下的资源,转换为流对象,前面隐藏当前工程的根目录
        InputStream is = servletContext.getResourceAsStream("file/config.properties");
        //1.创建属性对象
        Properties properties = new Properties();
        //2.指定载入数据源
//        InputStream is = new FileInputStream(path);
        properties.load(is);
        //3.获取address属性的值
        String address = properties.getProperty("address");
        System.out.println("address");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
  1. 存取数据,servlet 间共享数据,域对象【使用servletContext存取数据】
  • 定义一个登录的 html 界面,form 表单
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>请输入以下内容,完成登陆</h2>

    <form action="LoginServlet" method="get">
        账号:<input type="text" name="username"/><br>
        密码:<input type="text" name="password"/><br>
        <input type="submit" value="登陆"/>
    </form>
</body>
</html>
  • 定义 LoginServlet
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.获取数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username+password);
        //2.检验数据
        PrintWriter pw = response.getWriter();
        if("admin".equals(username) && "123".equals(password)){
            //成功的次数累加
            //获取以前的count值
            Object object = getServletContext().getAttribute("count");
            //默认是0次
            int totalCount = 0;
            if(object != null){
                totalCount = (int) object;
            }
            System.out.println("登录成功的次数是:" + totalCount);
            //给这个count赋新的值
            getServletContext().setAttribute("count", totalCount+1);
            //成功就跳转到success.html
            //设置状态码:重新定位状态码
            response.setStatus(302);
            //定位跳转的位置是哪一个页面
            response.setHeader("Location", "success.html");
        }else{
            pw.write("login failed...");
        }
    }
}

ServletContext 何时创建何时销毁?

服务器启动的时候,会为托管的每一个 web 应用程序创建一个 ServletContext 对象;从服务器移除托管或者关闭服务器会销毁它。

  • ServletContext 的作用范围
    只要在同一个项目中就可以。

HttpServletRequest

  • 这个对象封装了客户端提交过来的一切数据。
  1. 可以获得客户端请求头信息
public class ServletRequest extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //得到一个枚举集合
        Enumeration<String> headers = request.getHeaderNames();
        while(headers.hasMoreElements()){
            String name = headers.nextElement();
            String value = request.getHeader(name);
            System.out.println("name = " + name + " value = " + value);
        }
    }
}
  1. 获取客户提交过来的数据
//2.获取的是客户端提交上来的数据
        String name = request.getParameter("name");
        System.out.println("name" + name);

        //3.获取所有参数,得到一个枚举集合,一个key可以对应多个值
        Map<String, String[]> map = request.getParameterMap();
        Set<String> keySet = map.keySet();
        Iterator<String> iterator = keySet.iterator();
        while(iterator.hasNext()){
            String key = iterator.next();
            String[] value = map.get(key);
            System.out.println(key + "==" + value);
        }
  1. 获取中文数据

HttpServletResponse

  • 负责返回数据给客户端
  • 输入数据到页面上
//以字符流的方式写数据
        response.getWriter().write("hello");
        //以字节流的方式写数据
        response.getOutputStream().write("hello response...".getBytes());

相应的数据中有中文,有可能出现中文乱码

  • 字符流
    response.getWriter()
//相应的数据中包含中文,可能会出现乱码
        //这里写出去的文字默认使用的是ISO-8859-1,我们可以指定写出去的时候使用什么编码
        //1.指定输出到客户端的时候,这些文字使用UTF-8编码
        response.setCharacterEncoding("UTF-8");
//        response.getWriter().write("你好,今天天气不错!!!");

        //2.直接规定浏览器看这份数据的时候使用什么编码来看
        response.setHeader("Content-Type","text/html;charset=UTF-8");
        response.getWriter().write("你好,今天天气不错!!!");
  • 以字节流输出
    response.getOutputStream()
/**
         * 如果想让服务器端出去的中文在客户端能够正常显示,只要确保一点:
         * 出去的时候用的编码和客户端用的编码是一样的就可以了
         * 默认情况下getOutputStream输出使用的是UTF-8的码表
         */
        //设置向应的数据类型是html文本,并且告知浏览器使用UTF-8编码,这一句代码等于下边的两句,不管是字符还是字节流,只用这一行就行了
        response.setContentType("text/html;charset=UTF-8");
        //以字节流输出
        //1.指定输出的中文用的码表
        response.setHeader("Content-Type","text/html;charset=UTF-8");
        //2.指定浏览器看这份数据使用的码表
        response.getOutputStream().write("我爱中国!!!".getBytes("UTF-8"));

演练下载资源

  1. 直接以超链接的方式下载,不写任何代码,也能够下载下来东西。
让Tomcat的默认servlet去提供下载:<br>
    <a href="download/aa.jpg">aa.jpg</a><br>
    <a href="download/bb.txt">bb.txt</a><br>
    <a href="download/cc.rar">cc.rar</a><br>

这是因为Tomcat中有一个默认的servlet – DefaultServlet,这个 DefaultServlet 专门用于处理 Tomcat 服务器上的静态资源。

public class Demo extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取要下载的资源的名字
        String filename = request.getParameter("filename");
        //资源在Tomcat中的绝对路径地址
        String path = getServletContext().getRealPath("download/"+filename);
        //让浏览器收到这个资源的时候,以下载的方式提醒用户,而不是直接下载
        response.setHeader("Content-Dispositioin","attachment;filename=" + filename);
        InputStream is = new FileInputStream(path);
        OutputStream os = response.getOutputStream();
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = is.read(buffer)) != -1){
            os.write(buffer,0,len);
        }
        os.close();
        is.close();
    }
}

请求转发和重定向

重定向

if ("admin".equals(username) && "123".equals(password)){
            //早期写法
//            response.getStatus(302);
//            response.setHeader("Location","login_success.html");
            //重定向写法,重新定位方向
            response.sendRedirect("login_success.html");
            response.getWriter().write("登录成功");
        }else {
            response.getWriter().write("登录失败");
        }
  1. 地址上显示的是最后的那个资源的路径地址
  2. 请求次数最少两次,服务器在第一次接收请求后,会返回302以及一个地址,浏览器再根据这个地址执行第二次访问
  3. 可以跳转到任意路径,不是自己的工程也可以
  4. 效率上稍微低一些,因为要执行两次请求
  5. 后续的请求没法使用上一次请求request存储的数据,或者没法使用上一次的request对象,因为两次是不同的请求

请求转发

//请求转发写法
            request.getRequestDispatcher("login_success.html").forward(request,response);
  1. 地址上显示的是请求servlet的地址
  2. 请求次数上只有一次,因为服务器内部帮客户端执行了后续的工作
  3. 只能跳转自己项目的资源路径
  4. 效率上稍微高一些,因为执行一次请求
  5. 可以使用上一次request对象

Cookie

  • 饼干,其实是一份小数据,是服务器给客户端的,并且存储在客户端上的一份小数据
  • 应用场景
    自动登录、浏览记录、购物车

为什么要有 Cookie ?

http 的请求是无状态的。客户端与服务器在通讯的时候是无状态的,其实就是客户端在第二次来放的时候,服务器根本不知道这个客户端以前有没有来访过。

Cookie 怎么用?

  • 简单使用:
    1. 在响应的时候添加cookie
    2. 客户端收到的信息里面响应头中多了一个字段Set-Cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Cookie的简单使用

        //Cookie发送给客户端,并保存在客户端的一份小数据
        response.setContentType("text/html;charset=utf-8");

        //给响应添加一个cookie
        Cookie cookie = new Cookie("aa","bb");

        //给响应添加一个cookie
        response.addCookie(cookie);

        response.getWriter().write("请求成功!!!");

        //获取客户端带过来的cookie
        Cookie[] cookies = request.getCookies();
        if(cookies != null){
            for (Cookie c : cookies){
                String name = c.getName();
                String value = c.getValue();
                System.out.println("name = " + name + "value = " + value);
            }
        }
    }

Cookie 常用方法

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //取客户发送过来的cookie
        Cookie[] cookies = request.getCookies();

        if(cookies!= null){
            for (Cookie cookie : cookies){
                System.out.println(cookie.getName() + " = " + cookie.getValue());
            }
        }

        //先写cookie
        Cookie cookie1 = new Cookie("name", "Michael");
        //这个cookie的有效期,默认情况下,关闭浏览器后,cookie就没有了
        //正值:表示这个数字过后,cookie将会失效,以秒为单位
        //负值:表示关闭浏览器cookie就消失,默认值
        cookie1.setMaxAge(1000);

        //用于指定只有请求了指定的域名,才会带上该cookie
        cookie1.setDomain(".Michael.com");
        //只有访问该域名下的/ServletCookie2路径地址才会带cookie
        cookie1.setPath("/ServletCookie2");
        
        response.addCookie(cookie1);

        Cookie cookie2 = new Cookie("age", "18");
        response.addCookie(cookie2);

       
    }

例子一 显示上次访问时间

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8 ");

        String userName = request.getParameter("username");
        String password = request.getParameter("password");

        if("admin".equals(userName) && "123".equals(password)){
            //获取cookie
            Cookie[] cookies = request.getCookies();
            //从数组中找出我们想要的cookie
            Cookie cookie = CookieUtils.findCookie(cookies,"last");

            //第一次登录,没有cookie
            if(cookie == null){
                Cookie c = new Cookie("last",System.currentTimeMillis()+"");
                c.setMaxAge(60*60);
                response.addCookie(cookie);
            }else{
                //第二次登录,有cookie
                long lastVisitTime = Long.parseLong(cookie.getValue());
                response.getWriter().write("欢迎您!!!" + userName + "上次访问的时间是" + new Date(lastVisitTime));
                //重置登录时间
                cookie.setValue(System.currentTimeMillis()+"");
                response.addCookie(cookie);
            }
            response.getWriter().write("欢迎您!" + userName);
        }else {
            response.getWriter().write("登录失败!!!");
        }
    }

public class CookieUtils {
    public static Cookie findCookie(Cookie[] cookies, String name){
        if(cookies != null){
            for (Cookie cookie : cookies) {
                if(name.equals(cookie.getName()))
                    return cookie;
            }
        }
        return null;
    }

显示商品浏览记录

  1. 拷贝 heml 原型文件到web里面
  2. 在 web 下新建一个 jsp 文件,product_list.jsp,然后拷贝原来 product_list.html 的内容到 jsp 里面。
  3. 修改 product_info.html 超链接地址

cookie 总结

  1. 服务器给客户端发送过来的一小份数据,并且存放在客户端上
  2. 获取 cookie,添加cookie
    request.getCookie();
    response.addCookie();
  3. Cookie分类
    回话 cookie:默认情况下关闭浏览器,cookie 就会消失
    持久 cookie:在一定时间内都有效,并且会保存在客户端上
    cookie.setMaxAge(0); //设置立即删除
    cookie.setMaxAge(100); //100秒
  4. Cookie 的安全问题
    由于 cookie 会保存在客户端上,所以有安全隐患问题。还有一个问题,cookie 的大小与个数有限制。所以引出了 session。

Session

  • 会话,Session 是基于 Cookie 的一种会话机制。Cookie 是返回一小份数据给客户端,并且存放在客户端上。Session 是数据存放在服务器端上。
  • 常用 API
HttpSession session = request.getSession();

        //得到回话id
        String id = session.getId();
        //存值
        session.setAttribute();
        //取值
        session.getAttribute();
        //移除值
        session.removeAttribute();
  • Session 何时创建,何时销毁?
    创建:如果有在servlet中调用request.getSession();
    销毁:session 是存放在服务器内存中的一份数据,当然可以持久化,Redis。即使关了浏览器也不会销毁
  1. 关闭服务器
  2. session 会话时间过期,有效期过了,session 就会销毁了

简单购物车

在这里插入图片描述

移除 session 中的元素

//强制干掉会话,里面存放的任何数据都会消失
        session.invalidate();
        
        //从session中移除某一个数据
        session.removeAttribute("cart");
        //跳转页面

总结

  • 请求转发和重定向
    • Cookie
      服务器给客户端发送的一份小数据
      基本方法:
      添加cookie
      获取cookie
      什么时候有 cookie ?
      response.addCookie(new Cookie());
    • Cookie 分类
      会话cookie:关闭浏览器就失效
      持久cookie:存在客户端上,在指定的期限内有效
    • Session
      也是基于cookie的一种技术,数据存放在服务器端
      会在cookie里面添加一个字段 JSESSIONID,是tomcat服务器生成的。
      setAttribute() 存数据
      getAttribute() 取数据
      removeAttribute() 移除数据
      getSessionId() 获取会话id
      invalidate() 强制让会话失效

JSP

Java Server Page

  • 什么是 JSP ?
    从用户的角度来看就是一个网页,从程序员的角度看,其实就是一个 Java 类,它继承了 servlet ,所以可以直接说 JSP 就是一个servlet。
  • 为什么会有 JSP ?
    因为 html 多数情况下显示静态内容,是一成不变的。但是我们有时候需要在网页上显示一些动态数据,比如:查询所有学生信息,根据姓名查询具体某个学生,这些动作都需要去查询数据库,然后在网页上显示。HTML 不支持写 Java 代码,JSP 支持写 Java 代码。

如何使用 JSP ?

  • 指令的写法
    <%@ 指令名字%>
page 三大指令
  • language
    表明 JSP 页面中可以写 Java 代码
  • contentType
    其实就是说这个文件是什么类型,告诉浏览器我是什么类型,以及使用什么编码
contentType="text/html;charset=UTF-8"
  • import
    导包使用,一般不用手写

  • session
    值可选的有 true 或者 false
    用于控制在这个 JSP 页面里面能否直接使用 session 对象

  • errorPage
    指的是错误的页面,值需要给错误的页面路径(页面如果出错,则跳转到一个具体的页面)

  • isErrorPage
    上面的 errorPage 用于指定错误的时候跑到哪一个界面去。那么这个 isErrorPage 就是声明某一个页面到底是不是错误的页面。

inclde 指令

包含另外一个 JSP 的内容进来

<%@include file="other02.jsp"%>
  • include 背后细节
    把另外一个页面的内容拿过来一起输出,所有标签元素都包含进来。
taglib 标签
<%@taglib prefix="" uri="" %>
  • uri:标签库路径
  • prefix:标签库的别名

JSP 动作标签

  • jsp: include
    <jsp:include page="other02.jsp"></jsp:include>

作用:包含指定的页面,这里是动态包含,也就是不把包含的页面所有元素标签全部拿过来输出,而是把它的运行结果拿过来。

  • jsp: forward
    <jsp:forward page=""></jsp:forward>

前往哪一个页面

  • jsp:param
    在包含某个页面的时候,或者在跳转某个页面的时候,加入这个参数。

JSP 内置对象

  • 所谓内置对象就是我们可以直接在 JSP 页面中使用这些对象,不用创建
    • pageContext
    • request 对象:客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
    • response对象
      response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
    • session对象
      指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
    • out对象
      out对象是JspWriter类的实例,是向客户端输出内容常用的对象
    • page对象
      page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
    • application对象
      application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
    • exception对象
      exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
      以上四个是作用域对象
    • pageContext对象
      pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
    • config对象
      config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
  • 作用域
    表示这些对象可以存值,也可以取值。setAttribute 和 getAttribute
<%
        pageContext.setAttribute("name","page");
        request.setAttribute("name","request");
        session.setAttribute("name","session");
        application.setAttribute("name","application");
%>

    取出四个作用域中的值<br>

    <%= pageContext.getAttribute("name")%>
    <%= request.getAttribute("name")%>
    <%= session.getAttribute("name")%>
    <%= application.getAttribute("name")%>
四个作用域的区别
  • pageContext 【pageContext】
    作用域值仅限于当前页面,还可以获取到其他八个内置对象

  • request 【HttpSetvletRequest】
    仅限于一次请求,只要服务器对该请求做出了响应,这个域中存的值就没有了

  • session 【HttpSession】
    作用域限于一次会话(多次请求与响应)

  • application【servletContext】
    整个工程都可以访问,服务器关闭就不可以访问了

  • excption 【Throwable】

  • page 【Objext】就是这个JSP翻译成的Java类的实例对象

  • config 【SetvletConfig】

  • response 【HttpSetvletResponse】

  • out 【Jspwriter】

EL 表达式

是为了简化 jsp 代码,具体一点就是为了简化 jsp 里面的那些 Java 代码
写法格式:
${表达式}

如何使用
  • 取出四个作用域中存放的值
 <%
    pageContext.setAttribute("name","page");
    request.setAttribute("name","request");
    session.setAttribute("name","session");
    application.setAttribute("name","application");
    %>

    按普通手段取值<br>
    <%= pageContext.getAttribute("name")%>
    <%= request.getAttribute("name")%>
    <%= session.getAttribute("name")%>
    <%= application.getAttribute("name")%>

    使用EL表达式取出作用域中的值<br>
    ${pageScope.name}
    ${requestScope.name}
    ${sessionScope.name}
    ${applicationScope.name}
  • 如果域中所存的值是数组
取值细节
 从域中取值,先存值<br>
    <%
        pageContext.setAttribute("name","zhangsan");
        session.setAttribute("name","list");
    %>

    到这个作用域中去找这个name<br>
    ${pageScope.name}

    先从page中找,没有就去request中找,去session中找,去application中找<br>
    ${sessionScope.name}
  • 取值方式
    如果这份值是有下标的,那么直接使用 []
<%
    String[] array = {"aa", "bb", "cc"}
    session.setAttribute("array", array);
%>

${array[1]} 这里的array说的是attribute的name

如果没有下标,直接使用 . 的方式去取

<%
    User user = new User("zhangsan", 18);
    session.setAttribute("u", user);
    ${u.name}, ${u.age};
%>

一般 EL 表达式用的比较多的都是从一个对象中取出它的属性值,比如取出某个学生的姓名

EL 表达式的11个内置对象

${ 对象名.成员}

  • pageContext

  • 作用域相关对象

    • pageScope
    • requestScope
    • sessionScope
    • applicationScope
  • 头信息相关对象

    • header
    • headerValues

参数信息相关对象

  • param

  • params

  • cookie

全局初始化参数

  • initParam

JSTL

全称:JSP Standard Tab Library JSP标准标签库
简化 JSP 的代码编写,替换<%%>写法,一般与 EL 表达式配合

常用标签
  • c:set
 <%--声明一个对象name,对象值zhangsan,存储到了page(默认),指定是session--%>
    <c:set var="name" value="zhangsan"></c:set>
    ${name}
  • c:if
    判断test里面的表达式是否满足,如果满足就执行c:if标签中的输出。c:if 是没有 else 的
<%--声明一个对象name,对象值zhangsan,存储到了page(默认),指定是session--%>
    <c:set var="name" value="zhangsan"></c:set>
    ${sessionScope.name}
   
    <c:set var="age" value="18"></c:set>>
    <c:if test="${age>16}">
        年龄大于16...
    </c:if>

定义一个变量名 flag 去接收前面表达式的值,然后存在 session 域中

<c:set var="age" value="18"></c:set>>
    <c:if test="${age>16}" var="flag" scope="session">
        年龄大于16...
    </c:if>
  • c:foreach
    从1遍历到10,得到的结果赋值给i,并且会存储到 page 域中,step,幅度为2
<c:forEach begin="1" end="10" var="i" step="2">
        ${i}
    </c:forEach>
items:表示遍历哪一个对象,注意这里必须写EL表达式
    var:遍历出来的每一个元素使用user去接收
    <c:forEach var="user" items="${list}">
        ${user.name}-----${user.age}
    </c:forEach>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值