Servlet

Servlet

  • 开发动态web的一门技术

  • API 提供接口 servlet 二个步骤开发servlet程序

    • 编写一个类实现servlet接口

    • 把开发号的java类部署到web服务器中

实现了servlet接口的java程序叫做 servlet

Maven Servlet 和 jsp 依赖

<dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>
​
​
    </dependencies>

如何使用

  1. 构建一个Maven项目 删除src 在里面建立Moudel 空的工程就时Maven的主工程

  2. 关于Maven 父子类的理解

    • 在父项目中有

      <modules>
              <module>Servlet01</module>
          </modules>
    • 子项目里有 idea 有时候会消失 手动加上即可

      <parent>
        <artifactId>JavaWeb</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
      </parent>
  3. Maven 环境优化

    1. web.xml为最新的

      <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"
               metadata-complete="true">
      ​
      </web-app>

    2. 将maven的结构搭建完整

  4. 编写一个servlet

    1. 编写一个普通类

    2. 实现servlet接口 继承HttpServlet

      package com.chi.Servlet;
      ​
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.PrintWriter;
      ​
      public class HelloServlet 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 {
              super.doPost(req, resp);
          }
      }
      ​

  5. 编写Servlet的映射

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.chi.Servlet.HelloServlet</servlet-class>
    </servlet>  <--!-->com.chi.Servlet.HelloServlet 是java代码路径</--!-->
    ​
        <servlet-mapping>
            <servlet-name>HelloServlet</servlet-name>
            <url-pattern>/Hello</url-pattern>
        </servlet-mapping> <--!-->HelloServlet是于上面匹配即可  /Hello是打开指定这个网页时的名字 一定不要忘了斜杠</--!-->
  6. 配置Tomcat

  7. 启动测试

servlet 原理

Mapping 问题

  1. 一个Servlet 可以一处理一个映射路径

    • <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/Hello</url-pattern>
      </servlet-mapping>
  2. 一个Servlet 可以处理多个映射路径

    • <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/Hello</url-pattern>
      </servlet-mapping>
      ​
      <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/Hello1</url-pattern>
      </servlet-mapping>
      ​
      <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/Hello2</url-pattern>
      </servlet-mapping>

  3. 一个Servlet 可以只等通用映射路径

    • <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/Hello/*</url-pattern>
      </servlet-mapping>

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

    • <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>*.chi</url-pattern>
      </servlet-mapping>
      <!--只要以chi结尾就可以进入--> 
         
  5. 默认请求路径

    • <servlet-mapping>
          <servlet-name>HelloServlet</servlet-name>
          <url-pattern>/*</url-pattern>
      </servlet-mapping>
      <!--少用-->
  6. 优先级问题

    • 指定类固有的映射的优先级最高,如果没有在去找默认的处理请求了

ServletContext

web 容器在启动的时候,它会为每个web程序都创建一个servletContext对象来代表web应用

共享数据

我在这个servlet中保存的东西可以在别的servlet中使用

package com.chi.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//数据放入web容器
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Hello");
        ServletContext servletContext = this.getServletContext();
        String username = "帆船";
        servletContext.setAttribute("username",username); //一个数据保存在了web容器里
        
    }

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

package com.chi.servlet;

import javax.servlet.ServletContext;
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 GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        String username = (String) servletContext.getAttribute("username");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print(username);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}//在web.xml配置
<servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.chi.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>getc</servlet-name>
        <servlet-class>com.chi.servlet.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>getc</servlet-name>
        <url-pattern>/getc</url-pattern>
    </servlet-mapping>

获取初始数据

<context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>
package com.chi.servlet;

import javax.servlet.ServletContext;
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 ServletDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext=this.getServletContext();
        String url =servletContext.getInitParameter("url");
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}//在web.xml配置

请求转发

package com.chi.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
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 ServletDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("sd4");
        ServletContext servletContext=this.getServletContext();

        RequestDispatcher requestDispatcher =  servletContext.getRequestDispatcher("/gp"); //请求转发
        requestDispatcher.forward(req,resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
//在web.xml配置

读取资源文件

properties

  • 在java目录下resource 下创建properties 文件

在运行时所有的包都被打包到了一个路径下 target 里 在target里面找到classpath 用一个流来读取

username=root
password=123456
package com.chi.servlet;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ServletDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        InputStream is =this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properies =new Properties();
        properies.load(is);
        String username = properies.getProperty("username");
        String password = properies.getProperty("password");
        resp.getWriter().print(username+":"+password);
    	is.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
//在web.xml配置

HttpServletResponse

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

  • 如果需要获取客户端请求过来的参数:找HttpServletRequest

  • 如果需要客户端响应一些信息:HttpServletResponse

向浏览器发送数据的方法

public interface ServletResponse {
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. 下载文件

    • 获取下载文件的路径

    • 下载的文件名

    • 让浏览器能够支持我们需要下载的东西

    • 获取下载文件的输入流

    • 创建缓冲区

    • 获取OutputStream对象

    • 将FileOutputStream写入缓冲区buffer

    • OutputStream将缓冲区的数据输出到客户端

package com.chi.Servlet;

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

public class Response extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //- 获取下载文件的路径
        String realPath = "D:\\Learning\\JavaWeb\\Response\\target\\classes\\1.png";
        System.out.println("下载路径: "+ realPath);
        //- 下载的文件名
        String fileName =realPath.substring(realPath.lastIndexOf("\\")+1);
        //- 让浏览器能够支持我们需要下载的东西
        resp.setHeader("Content-Disposition","attachment;fileName="+fileName);
        //- 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        //- 创建缓冲区
        int len =0;
        byte[] buffer = new byte[1024];
        //- 获取OutputStream对象
        ServletOutputStream out = resp.getOutputStream();
        //- 将FileOutputStream写入缓冲区buffer   //- OutputStream将缓冲区的数据输出到客户端
        while((len=in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        out.close();
        in.close();

    } //别忘了配置web.xml
   

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

验证码

验证码怎么来:

  • 前端实现

  • 后端实现,需要使用java的一个图片类,生产一个图片

    package com.chi.Servlet;
    
    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;
    import java.util.Random;
    
    public class ImageServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //如何让浏览器5秒自动刷新一次
            resp.setHeader("refresh","3");
            //在内存中创建一个图片
            BufferedImage bufferedImage = new BufferedImage(80,30,BufferedImage.TYPE_INT_RGB);
            //得到图片
            Graphics2D g =(Graphics2D) bufferedImage.getGraphics(); //笔
            //设置图片的背景颜色
            g.setColor(Color.white);
            g.fillRect(0,0,80,20);
            //给图片写数据
            g.setColor(Color.blue);
            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-chache");
            resp.setHeader("Pragma","no-chache");
            //把图片写给浏览器
            ImageIO.write(bufferedImage,"jpeg",resp.getOutputStream());
    
        }
        private String makeNum(){
            Random number = new Random();
            String RandomNumber=number.nextInt(9999999)+"";
           StringBuffer stringBuffer = new StringBuffer();
            for (int i = 0; i < 7-RandomNumber.length(); i++) {
                stringBuffer.append("0");
            }
            RandomNumber=stringBuffer.toString()+RandomNumber;
            return RandomNumber;
        }
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }

重定向

一个web 资源收到客户端请求和 他会通知客户端去访问另外一个web资源 这个过程叫做重定向

常见场景:

  • 用户登录 :登录完成重定向

    void sendRedirect(String var1) throws IOException;
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        resp.setHeader("Loction","/redirect/img");
//        resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
       //下面一行等于上面两行
     resp.sendRedirect("/redirect/img");
    }

<html>
<body>
<h2>Hello World!</h2>
<%--${pageContext.request.contextPath}当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    UserName: <input type="text" name="username"><br>
    PassWord: <input type="password" name="password"><br>
    <input type="submit">
</form>


</body
   
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>Success!!!!</h1>

</body>
</html>
  
package com.chi.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 ResquestTest extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String name =req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(name+" : "+password);
        //重定向
        resp.sendRedirect("success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}//不要忘记配置 web.xml
<servlet>
    <servlet-name>request</servlet-name>
    <servlet-class>com.chi.Servlet.ResquestTest</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>request</servlet-name>
    <url-pattern>/login</url-pattern>
</servlet-mapping>

HttppServeltRequest

HttppServeltRequest代表客户端的请求,用户通过Http协议访问服务器, http请求中的所有今昔会封装到HttppServeltRequest, 通过这个方法可以获得客户端所有的信息

req.getParameter(""); //单个
req.getParameterValues(""); //多个
package com.chi.Servlet;

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

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name =req.getParameter("username");
        String password =req.getParameter("password");
        String []hobby =req.getParameterValues("hobby");
        System.out.println(name);
        System.out.println(password);
        System.out.println(Arrays.toString(hobby));
        //转发请求
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值