JavaWeb学习(二):Servlet

本文详细介绍了Servlet的原理和应用,从Servlet简介、运行过程到实现类,深入讲解doGet和doPost的区别,以及如何在IDEA中开发Servlet。此外,还探讨了Response的重定向、ServletContext的应用,以及Request的处理和会话管理,涵盖了Cookie和Session的使用。
摘要由CSDN通过智能技术生成

一、Servlet简介

  • Servlet是Sun公司提供的也可用于开发动态web资源的技术
  • Sun公司在其API中提供了一个Servlet接口,用户若想发一个动态web资源,需两个步骤:
    • 编写一个Java类,实现Servlet接口
    • 八开发好的Java类部署到web服务器中
  • 按照一种约定俗称的称呼习惯,通常我们也把实现了Servlet接口的Java程序称之为Servlet

二、Servlet运行过程

  1. Web浏览器发出HTTP请求给Web容器
  2. Web容器首次访问创建目标Servlet
  3. Web容器创建请求(request)和创建响应(response)
  4. Web容器调用Servlet.service(request,response)
  5. service(request,response)获取请求信息。并把响应写入响应信息返回给Web容器
  6. Web容器发出HTTP响应给Web浏览器
  • 注意:service() 方法由容器调用,开发人员不用对 service() 方法做任何动作,只需要根据来自客户端的请求类型来重写 doGet() 或 doPost() 即可

三、Servlet实现类

  • Servlet接口Sun公司定义了两个默认实现类。分别为GenericServlet、HttpServlet
  • HttpServlet是指能够处理Http请求的Servlet,它在原有的Servlet接口上添加了一些与HTTP协议处理方法,它比原有接口功能更强大,因此通常使用该类,由于在实现Servlet接口时覆写了service方法,该方法体内的代码会自动判断用户的请求方法,因此在编写Servlet时,通常只需要覆写doGet和doPost方法,而不需要去覆写service方法

四、doGet和doPost的区别

  • form运行方式

    • 当form框里面的method为get时,执行doGet方法
    • 当form框里面的method为post时,执行doPost方法
  • 生成方式

    • doGet有四种:
      • 直接在URL地址栏中输入URL
      • 网页中的超链接
      • form中method为get
      • form中method为空时,默认是get提交
    • doPost只有一种
      • form中method属性为post
  • 数据传输方式

    • doGet方式:表单数据存放在URL地址后面。所有get方式提交时HTTP中没有消息体
    • doPost方式:表单数据存放在HTTP协议的消息体中以实体的方式传送到服务器
  • 服务器获取数据方式

    • doGet方式:服务器采用request.QueryString来获取变量的值
    • doPost方式:服务器采用request.Form来获取数据
  • 传送的数据量

    • doGet:数据量长度有限制,一般不超过2kb。因为是参数传递,且在地址栏中,故数据量有限制
    • doPost:适合大规模的数据传送。因为是以实体的方式传送的。
  • 安全性

    • doGet:安全性差。因为是直接将数据显示在地址栏中,浏览器有缓冲,可记录用户信息。所以安全性低
    • doPost:安全性高。因为post方式提交数据时是采用的HTTP post机制,是将表单中的字段与值放置在HTTP HEADER内一起传送到ACTION所指的URL中,用户是看不见的
  • 在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式

五、使用IEDA开发Servlet

  1. 准备Servlet需要的jar包
  2. 在IEDA中新建一个Web项目
  3. 新建一个Servlet
  4. 编写代码
  5. 配置web.xml中Servlet的servlet和servlet-mapping
  6. 启动Tomcat服务器
  7. 访问Servlet编写的网页
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletTest03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.getWriter().println("<h1>Hello Servlet</h1>");
    }

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

配置xml:

<?xml version="1.0" encoding="UTF-8"?>
<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">

    <servlet>
        <servlet-name>Test03</servlet-name>
        <servlet-class>com.kuang.servlet.ServletTest03</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>Test03</servlet-name>
        <url-pattern>/aaa</url-pattern>
    </servlet-mapping>
</web-app>

启动服务器发布后:

注意:一般情况下一个URL对应一个请求

六、Response——重定向

当文档移动到新的位置,我们需要向客户端发送这个新位置时,我们需要用到网页重定向。重定向请求到另一个网页的最简单的方式是使用 response 对象的 sendRedirect(String s) 方法,参数需传递新的网页URL

注意

  • 使用sendRedirect(String s) 方法时,若想跳转到本服务器下的其他页面,则传入该页面的URL,重定向后地址栏最后的URL值会改变

    例如重定向到本服务器的404.jsp时:

    response.sendRedirect("404.jap");
    
  • 使用sendRedirect(String s) 方法跳转到其他服务器的页面时,直接传入新页面的完整网址,包括HTTP或HTTPS协议,否则将重定向失败

    例如需要重定向到百度首页时:

    response.sendRedirect("https://www.baidu.com");
    

七、Response——ServletContext

  • Web容器在启动时,它会为每一个Web应用程序创建一个对应的ServletContext对象,它代表当前对象的引用

  • 通过ServletContext对象实现数据共享

    发送端:

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet(name = "ServletDemo03")
    public class ServletDemo03 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //通过Servlet对象可获取一个ServletContext对象
            ServletContext servletContext = this.getServletContext();
            String name = "华为";
            //通过setAttribute方法向ServletContext发送数据
            servletContext.setAttribute("name",name);
            response.setCharacterEncoding("utf-8");
            response.getWriter().print("设置name成功:"+name);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    

    接收端:

    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet(name = "ServletDemo04")
    public class ServletDemo04 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext servletContext = this.getServletContext();
            //通过getAttribute方法向ServletContext接收数据
            Object name = servletContext.getAttribute("name");
            response.setCharacterEncoding("utf-8");
            response.getWriter().println("接收到的name:"+name);
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    
  • 通过ServletContext读取网站配置文件

    1. 新建一个properties文件
    driver=com.mysql.jdbc.Driver
    username=root
    password=123456
    url=jdbc:mysql://localhost:3306/smbms
    
    1. 编写Servlet类
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    //读取properties配置文件
    public class ServletDemo03 extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //读取配置文件
    
            //1.获得配置文件的路径
            String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/resources/database.properties");
            System.out.println("取得的路径为:"+realPath);
    
            Properties properties = new Properties();
            FileInputStream is = new FileInputStream(realPath);
    
            properties.load(is);//把文件流加载到配置文件的对象中;
    
            String driver = properties.getProperty("driver");
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            String url = properties.getProperty("url");
    
    
            //响应到网页
            resp.getWriter().println(driver);
            resp.getWriter().println(username);
            resp.getWriter().println(password);
            resp.getWriter().println(url);
        }
    }
    
    1. 配置web.xml
    2. 访问

    注意:配置文件路径在src下(在src下新建resources文件夹)!!!

八、简单验证码的实现

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;

//验证码
public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //自动刷新网页:--->   refresh 刷新网页, 2时间
        resp.setHeader("refresh","2");

        //验证码是一个图片 , 我们需要制作一个图片
        BufferedImage image = new BufferedImage(100,30,BufferedImage.TYPE_3BYTE_BGR);

        //图片写入一些东西
        Graphics2D graphics = image.createGraphics();
        graphics.setColor(Color.red);
        String num = String.valueOf(newRandom());
        graphics.drawString(num,10,10);

        //想办法让浏览器知道我们给的是一张图片
        resp.setContentType("image/jpg");

        //让网站去打开图片
        ImageIO.write(image,"jpg",resp.getOutputStream());
    }

    //生成随机数
    public int newRandom(){
        int num = (int) Math.ceil(Math.random()*10000);
        return num;
    }
}

九、Request——获取项目信息

  • jsp获取项目路径

    ${pageContext.request.contextPath}
    
  • Request对象

    Request对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    public class RequestDemo01 extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //查看request对象的方式
            System.out.println(request.getContextPath()); //获得web项目路径
            System.out.println(request.getRequestURI()); //请求的URL路径
            //Remote 远程
            System.out.println(request.getRemoteUser()); //获得远程的用户名
            System.out.println(request.getRequestedSessionId()); //获得SessionId;
            System.out.println(request.getServletPath()); //请求servlet的url
            System.out.println(request.getLocalAddr()); //获得本地地址  防火墙
            System.out.println(request.getLocalName()); //获得本地名字
            System.out.println(request.getLocalPort()); //获得访问的端口号
    
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doPost(request,response);
        }
    }
    

十、Request——接收前端用户提交的数据&请求转发

  1. 登录页面jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录</title>
    </head>
    <body>
    <h1>登录</h1>
    
    <form action="${pageContext.request.contextPath}/a" method="post">
    
        <p>用户名:<input type="text" name="username"></p>
        <p>密码:<input type="password" name="password"></p>
    
        <p>
            <input type="submit">
            <input type="reset">
        </p>
    
    </form>
    </body>
    </html>
    
    
  2. 成功页面jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登录成功</title>
    </head>
    <body>
    <h1>登录成功</h1>
    </body>
    </html>
    
  3. 接收前端传递的控件信息:request.getParameter(“控件的name‘);

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class RequestDemo01 extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            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");
    
            if (username.equals("admin") && password.equals("123456")){
                System.out.println("登陆成功");
    
                //转发
               //转发:服务器把这个请求转向另外一个Servlet去处理; (地址栏不会变)
            //RequestDispatcher ,需要使用RequestDispatcher来进行处理,我们需要获得这个类,参数为要转发到的页面
                req.getRequestDispatcher("/page/success.jsp").forward(req,resp);
            }else {
                System.out.println("登陆失败");
            }
    
    
        }
    }
    
    
  • 转发
    1. 通过ServletContext的getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
    2. 通过request对象提供的getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发

十一、转发和重定向的区别

  • 重定向:服务器告诉客户端去请求另外一个地址,属于客户端行为,地址栏会改变,不能携带参数(302)
  • 转发:服务器自己转发到服务器上的另一个请求,属于服务器行为,地址栏不会变,可以携带参数(307)

十二、会话

  • 概念

    在Web中,会话表示从浏览器打开某个网站,在这个网站中无论操作了什么,直到关闭浏览器,这一个过程,称之为一个会话。

  • 怎样算会话结束

    • 客户端关闭了
    • 服务器销毁了
  • 为什么要处理会话

    长期保持会话,无论用户关闭多少次浏览器,这个会话都存在(如虎牙的一个月免登录)

  • 保存会话的两种机制

    • Cookie:

      Cookie是客户端机制,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了

      好比超市给用户的会员卡,下次带去就知道之前来过

    • Session

      Session是服务器端技术,利用这个机制,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。

      好比超市在自己的系统上保存了用户的信息,用户下次去直接说会员名就行

十三、Cookie

构造器:

Cookie cookie = new Cookie(String name,String value);

服务器响应Cookie给客户端:

response.addCookie(Cookie);

服务器查看用户带来的请求是否有Cookie

Cookie[] cookies = Request.getCookie();
//可以使用cookie来验证用户是否来过
//判断cookies是否为空,然后遍历即可
Cookie.getName();
Cookie.getValue();
No.方法类型描述
1Cookie(String name, String value)构造方法实例化Cookie对象,传入cooke名称和cookie的值
2public String getName()普通方法取得Cookie的名字
3public String getValue()普通方法取得Cookie的值
4public void setValue(String newValue)普通方法设置Cookie的值
5public void setMaxAge(int expiry)普通方法设置Cookie的最大保存时间,即cookie的有效期,当服务器给浏览器回送一个cookie时,如果在服务器端没有调用setMaxAge方法设置cookie的有效期,那么cookie的有效期只在一次会话过程中有效,用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一次会话,当用户关闭浏览器,会话就结束了,此时cookie就会失效,如果在服务器端使用setMaxAge方法设置了cookie的有效期,比如设置了30分钟,那么当服务器把cookie发送给浏览器时,此时cookie就会在客户端的硬盘上存储30分钟,在30分钟内,即使浏览器关了,cookie依然存在,在30分钟内,打开浏览器访问服务器时,浏览器都会把cookie一起带上,这样就可以在服务器端获取到客户端浏览器传递过来的cookie里面的信息了,这就是cookie设置maxAge和不设置maxAge的区别,不设置maxAge,那么cookie就只在一次会话中有效,一旦用户关闭了浏览器,那么cookie就没有了,那么浏览器是怎么做到这一点的呢,我们启动一个浏览器,就相当于启动一个应用程序,而服务器回送的cookie首先是存在浏览器的缓存中的,当浏览器关闭时,浏览器的缓存自然就没有了,所以存储在缓存中的cookie自然就被清掉了,而如果设置了cookie的有效期,那么浏览器在关闭时,就会把缓存中的cookie写到硬盘上存储起来,这样cookie就能够一直存在了。
6public int getMaxAge()普通方法获取Cookies的有效期
7public void setPath(String uri)普通方法设置cookie的有效路径,比如把cookie的有效路径设置为"/xdp",那么浏览器访问"xdp"目录下的web资源时,都会带上cookie,再比如把cookie的有效路径设置为"/xdp/gacl",那么浏览器只有在访问"xdp"目录下的"gacl"这个目录里面的web资源时才会带上cookie一起访问,而当访问"xdp"目录下的web资源时,浏览器是不带cookie的
8public String getPath()普通方法获取cookie的有效路径
9public void setDomain(String pattern)普通方法设置cookie的有效域
10public String getDomain()普通方法获取cookie的有效域

Cookie测试用户是否来过

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CookieDemo extends HttpServlet {
    Cookie cookie = null;
    Boolean flag = false;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        Cookie[] cookies = req.getCookies();
        if (flag){
            resp.getWriter().println("上次登录时间为"+ cookie.getValue());
            resp.getWriter().println("刷新了Cookie");
        }else {
            resp.getWriter().println("第一次来没有Cookie");
        }
        cookie = new Cookie("LastLoginTime",System.currentTimeMillis()+"");
        resp.addCookie(cookie);
        flag=true;
    }
}

十四、Session

  • 只要客户端一旦连接上服务器,服务器就会自动产生Session,一个连接对应一个session,session可以在一个会话中传递信息
  • 通过setAttribute设置值
  • 通过getAttribute获得值
  • Session由服务器控制,如果服务器重启了,信息就会丢失

使用Session存入值:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

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

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

        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");

        //session由服务器创建

        //得到的session对象
        HttpSession session = req.getSession();

        String id = session.getId();

        resp.getWriter().println("获得的sessionId"+id);

        String name = "小学生";
        session.setAttribute("name",name);
        resp.getWriter().println("设置session成功:"+name);

    }
}

获取Session存入的值:

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RequestDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        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");

        if (username.equals("admin") && password.equals("123456")){
            System.out.println("登陆成功");

            //转发
            req.getRequestDispatcher("/page/success.jsp").forward(req,resp);
        }else {
            System.out.println("登陆失败");
        }


    }
}

  • 会话注销的方式一
session.invalidate();//通过代码注销会话
  • 会话注销的方式二
<!--session-config可以设置会话自动过期,时间分钟为单位-->
<session-config>
    <session-timeout>1</session-timeout>
</session-config>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值