Hello Servlet

目录

1、什么是servlet

2、HelloServlet

2.1、创建一个Maven项目

问题:

2.2、原理

 3、Mapping

4、ServletContext

5、HttpServletResponse

5.1、常见应用

5.2、验证码功能

5.3、实现重定向

5.4、重定向和转发的区别

6、HttpServletRequest 

7、Session、Cookie

7.1、会话

7.2、保存会话的两种技术

7.3、Cookie

7.4、Session*


1、什么是servlet

  • Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
  • 使用 Servlet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
  • Sun公司在这些API中提供一个接口叫servlet
  • 如果想开发一个servlet程序,只需要完成两个步骤:1、编写一个类,实现Servlet接口。2、把开发好的Java类部署到服务器中
  • 把实现了Servlet接口的Java程序叫做,Serlet

2、HelloServlet

2.1、创建一个Maven项目

  • 创键一个父Maven项目,创建web项目时都以这个父项目为基础。
  • 在父maven项目pom中配置servlet依赖和jsp依赖,这样子模块共同使用方便。
  •  <!--加入servlet依赖(servlet的jar)-->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>4.0.1</version>
                <scope>provided</scope>
            </dependency>
            <!--jsp的依赖(jsp相关的jar加进来)-->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>javax.servlet.jsp-api</artifactId>
                <version>2.3.3</version>
                <scope>provided</scope>
            </dependency>
  • 在src\main下创建Java文件标志成蓝色源文件,与之并行创建resourcess资源文件。
  • 在Java文件中创建com.***.servlet文件再创建HelloServlet类让其继承HttpServlet类,重写doGet和doPost方法。添加响应流输出(hello servlet)。
  • 打开web.xml文件注册servlet和编写映射。
  • <!--注册servlet-->
        <servlet>
            <servlet-name>hello</servlet-name>
            <servlet-class>com.zhang.servlet.HelloServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <!-- servlet的请求路径-->
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>

    配置tomcat将servlet01.war部署到服务器上端口后路劲名改为s1(为了方便)启动tomcat运行正常情况浏览器显示hello world。

问题:

出现404找不到资源,检查发现自己构造的没有在子模块党的pom文件中声明打包方式为war,导致项目打包出错,同时webapp的蓝点也没亮,在模块设置中添加web将wabapp路经写入即可,重新运行服务器就正常了。

2.2、原理

servlet是由web服务器调用,web服务器在收到浏览器请求之后,会判断servlet是否存在,若不存在则装载创建servlet的实例并初始化(若存在则跳过此步骤),然后调用service方法对请求进行处理。

 3、Mapping

1.一个servlet指定多个映射路经

<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello1</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello2</url-pattern>
    </servlet-mapping>

2.一个servlet指定通用映射路劲

<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>

3.默认请求路经

 <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

4.指定一些后缀或者前缀。

<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
一般是.do

5.优先级问题

指定了固有的映射路劲优先级最高,如果找不到路劲就走默认处理请求。

4、ServletContext

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

用处:

  1. 共享数据  在这个Servlet中保存的数据,可以在另外一个servlet中拿到使用
  2. 首先需要一个放置数据的类
    
    
    System.out.println("进入doget方法");
            //this.getInitParameter()   初始化参数
            //this.getServletConfig()    servlet配置
            //this.getServletContext()   servlet上下文
            ServletContext servletContext = this.getServletContext();
            String username = "张三";//数据
            servletContext.setAttribute("username",username);//将一个数据保存在了ServletContext中  名字为:useername  值:username
    然后再写一个读取数据的类  
    ServletContext servletContext = this.getServletContext();
            String username = (String) servletContext.getAttribute("username");
    
    
            resp.setContentType("text/html");
            resp.setCharacterEncoding("utf-8");
            resp.getWriter().println(username);

  3. 获取初始化参数

  4. ServletContext servletContext = this.getServletContext();
    
            String url = servletContext.getInitParameter("url");
            resp.getWriter().println(url);
    设置初始参数
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
      </context-param>

  获取请求转换

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("000000000000");
        RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/gp");//获取请求转换路劲
        requestDispatcher.forward(req,resp);//调用forward实现请求转发


    }

   

读取资源文件

Properties

  • 在Java目录下创建properties
  • 在resources目录下新建properties
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String username = properties.getProperty("username");
        String pwd = properties.getProperty("password");
        resp.getWriter().println(username+":"+pwd);

    }
username = root123
password = 00000000

5、HttpServletResponse

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

和一个代表响应的HttpServletResponse;

  • 如果要获得客户端请求过来的参数:找HttpServletRequest 
  • 如果要获得客户端响应的信息:找HttpServletResponse

5.1、常见应用

  1. 向浏览器输出信息(print)
  2. 下载文件
  • 要获取下载的文件路径
  • 下载的文件名
  • 设置让浏览器能支持下载我们需要的东西
  • 获取下载文件的输入流
  • 创建缓冲区
  • 获取OutputStresm对象
  • 将FileOutputStresm流写入到buffer缓冲区
  • 使用OutputStresm将缓冲区中的数据输出到客户端
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //要获取下载的文件路径
    String realPath ="D:\\maven-workspace\\space02\\javaweb-04-servlet\\response\\target\\response\\WEB-INF\\classes\\这是个图片.jpg";
    System.out.println("下载文件的路经:"+realPath);
    //下载的文件名
    String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
    //设置让浏览器能支持(Content-Disposition)下载我们需要的东西
    resp.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(filename,"UTF-8"));
    //获取下载文件的输入流
    FileInputStream fileInputStream = new FileInputStream(realPath);
    //创建缓冲区
    int len=0;
    byte[] buffer = new byte[1024];
    //获取OutputStresm对象
    ServletOutputStream outputStream = resp.getOutputStream();
    //将FileOutputStresm流写入到buffer缓冲区
    while ((len=fileInputStream.read(buffer))>0){
            outputStream.write(buffer,0,len);
        };
    //使用OutputStresm将缓冲区中的数据输出到客户端
    fileInputStream.close();
    outputStream.close();
     System.out.println(outputStream);
    }

5.2、验证码功能

前后端都可实现验证码

后端需要用  Java 的图片类加载出一个图片

 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //让浏览器3秒刷新一次
        resp.setHeader("refresh","3");
    //在内存中创建一个图片
        BufferedImage image = new BufferedImage(40, 20, BufferedImage.TYPE_INT_RGB);
    //得到图片
        Graphics2D g = (Graphics2D) image.getGraphics();
        g.setColor(Color.cyan);
        g.fillRect(0,0,40,20);
    //给图片写数据
    g.setColor(Color.magenta);
    g.setFont(new Font(null,Font.BOLD,20));
    g.drawString(makeNum(),0,20);
    //告诉浏览器,这个请求用图片的方式打开
    resp.setContentType("image/jpg");
    //网站存在缓存,设置浏览器不缓存
        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 s = random.nextInt(999999)+"";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 6-s.length(); i++) {
            sb.append("0");
        }
        s=sb.toString()+s;
        return s;
    }

5.3、实现重定向

 B一个web资源收到客户端A请求后,B会通知客户端A去访问另一个web资源C,这个过程叫做重定向。

场景:

  • 登录

 

/*resp.setHeader("Location","/r/img");
  resp.setStatus(302);
*/
resp.sendRedirect("/r/img");

5.4、重定向和转发的区别

相同点:

  • 页面都会跳转

不同点:

  • 请求转发的时候,URL不会发生变化   状态码:307
  • 重定向时候,URL地址栏会发生变化   状态码:302

6、HttpServletRequest 

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

 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[] hobbies = req.getParameterValues("hobby");
        System.out.println("-----------------------");
        //后台接收中文乱码问题
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbies));
        System.out.println("-----------------------");
        //通过请求转发
        resp.sendRedirect("/re/success.jsp");
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
<h1>登录</h1>
<div style="text-align: center">
    <form action="${pageContext.request.contextPath}/login" method="post">
        用户名:<input type="text" name="username"> <br>
        密码:<input type="password" name="password"> <br>
        学校:
        <input type="checkbox" name="hobby" value="清华">清华
        <input type="checkbox" name="hobby" value="北大">北大
        <input type="checkbox" name="hobby" value="浙大">浙大
        <input type="checkbox" name="hobby" value="复旦">复旦
        <input type="checkbox" name="hobby" value="武大">武大
        <br>
        <input type="submit">
    </form>
</div>
</body>
</html>

7、Session、Cookie

7.1、会话

会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。

有状态会话:可以在交互的同时,保持住状态(与会话的区别)。 此类场景的一个常见示例是我们正在使用的一个监视进程的会话。 理想情况下,我们想越快越好的向所监控的进程中插入任何传入事件,也希望尽快发现问题。

一个网站怎么证明你来过?

客户端      服务端

  1. 服务端给客户端一个信封,客户端下次访问服务器端带上信件就可以了;cookie
  2. 服务器登记你来过了,下次你来的时候我来匹配你;session

7.2、保存会话的两种技术

cookie

客户端技术(响应,请求)

session

服务器技术,利用这个技术可以保存用户的会话信息,我们可以把信息放在Session中

一些网站一次登录后,短时间内再访问就不用登录了。

7.3、Cookie

1、从请求中拿到cookie信息

2、服务器响应给客户端cookie

//cookie 服务器端从客户端获取
        Cookie[] cookies = req.getCookies();
    //判断cookie是否存在
        if (cookies!=null){
            out.write("你上一次访问的时间是:");
            for (int i = 0; i <cookies.length ; i++) {
                Cookie cookie = cookies[i];
                //获取cookie的名字
                if (cookie.getName().equals("lastLoginTime")){
                    //获取cookie的值
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    out.write(date.toLocaleString());
                }
            }
        }else {
            out.write("这是你第一次访问本站");
        }
        //服务给客户端响应一个coolie
        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
       //设置有效时间
        cookie.setMaxAge(24*60*60);
        resp.addCookie(cookie);

cookie一般保存在本地用户目录appdata下

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

删除Cookie:

1、不设置有效时间,关闭浏览器自动失效;

2、设置有效时间为0;

7.4、Session*

什么是session:

  • 服务器会给每一个用户(浏览器)创建一个session对象;
  • 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在;
  • 用户登录之后,整个网站它都可以访问;
 //解决乱码
        resp.setContentType("text/html;charset=utf-8");
        //得到session
        HttpSession session = req.getSession();
        //给session中存东西
        session.setAttribute("name",new Person("张三",18));
        //获取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 jsessionid = new Cookie("JSESSIONID", sessionId);
        //resp.addCookie(jsessionid);

Session和Cookie的区别:

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

使用场景:
1、保存用户登录信息;

2、购物车信息;

3、在整个网站中经常会使用的数据,我们将它保存在session中;

会话过期:

自动
<session-config>
<!--1分钟   以分钟为单位-->
  <session-timeout>1</session-timeout>
</session-config>
//手动注销session
session.invalidate();
posted @ 2022-07-29 16:12  Fiercezm  阅读(44)  评论(0编辑  收藏  举报  来源