目录

1.Servlet简介

1.1 Servlet概述

1.2 HelloServlet

1.3、Servlet原理

1.4 Mapping问题

1.5 ServletContest

1.6 HttpServletResponse

1.6.1 简单分类

1.6.2 常见应用

1.6.3 验证码功能

1.6.4 实现重定向

1.7 HttpServletRequest

1.7.1 获取前端传来的参数


1.Servlet简介

1.1 Servlet概述

      1.  servlet就是sun公司开动态web的一门技术

        2.sun公司在这些API中提供了一个接口叫做:servlet,如果想开发一个servlet程序,只需要完成两个小步骤:

                (1)编写一个类,实现servlet接口

                (2)把开发好的Java类部署web服务器中

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

1.2 HelloServlet

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

1.构建一个普通的Maven项目,删掉里面的src目录,这个空的工程就是Maven主工程。

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

        父项目中会有:

<modules>
        <module>servlet-01</module>
</modules>

        子项目会有:

<parent>
        <artifactId>JavaWebStudy</artifactId>
        <groupId>com.liu</groupId>
        <version>1.0-SNAPSHOT</version>
</parent>

        父项目中的java子项目可以直接使用

son extends father

 3.Maven环境优化

        1.将web.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">
</web-app>

        2.将maven的结构搭建完整

4.编写一个Servlet程序

        1.编写一个普通类

        2.实现servlet接口,这里我们直接继承HttpServlet

        ps:ctrl+鼠标左键(查看源码)

public class HelloServlet extends HttpServlet {
    //由于get或者post只是请求实现的不同方式,可以互相调用,业务逻辑都一样
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer=response.getWriter();//响应流
        writer.print("Hello Servlet");
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

5.编写Servlet的映射

        为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给他一个浏览器能够访问的路径。

    <!--注册Servlet-->
    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet请求路径-->
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

6.配置Tomcat

        注意:配置项目发布的路径就可以了。

7.启动测试,OK

1.3、Servlet原理

1.4 Mapping问题

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

<servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
</servlet>

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>/hello2</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello3</url-pattern>
</servlet-mapping>

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

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

注意点:如果路径只写/*

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

ps:此时重启Tomcat,页面会优先加载服务器请求,而不会走静态资源路径。

4.可以自定义后缀实现请求映射(此时 * 前面不能加项目映射的路径)

<servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
</servlet-mapping>

5.优先级问题

指定了固定的映射路径优先级最高,如果找不到就会走默认的请求处理(案例自定义404);

<servlet>
    <servlet-name>error</servlet-name>
    <servlet-class>com.liu.servlet_01.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>error</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

1.5 ServletContest

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

        共享数据:我在这个servlet中保存的数据,可以在其他的servlet中取到。

一次性设置两个编码:

resp.setContentType("text/html; charset=utf-8");

 Helloservlet(存放一个数据)

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        this.getInitParameter()  初始化参数
//        this.getServletConfig() Servlet配置
//        this.getServletContext() Servlet上下文
        ServletContext context=this.getServletContext();
        String username="liuSir";//数据
        context.setAttribute("username",username);//将一个数据保存在了ServletContext中,名字为:username 值为:username(键值对形式)
    }

 GetServlet(取出其他Servlet存放的数据)

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String username= (String) context.getAttribute("username");
        //解决乱码问题
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        response.getWriter().print("username:"+username);
        //解决编码问题:写在一行中的方法如下:
        response.setContentType("text/html; charset=utf-8");
    }

配置web.xml:

     <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.liu.servlet_01.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>GetServlet</servlet-name>
        <servlet-class>com.liu.servlet_01.GetServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetServlet</servlet-name>
        <url-pattern>/gets</url-pattern>
    </servlet-mapping>

测试访问:如果先访问\hello路径,然后访问/gets路径,会发现页面输出有结果;如果先访问/gets路径,会发现页面只输出"username:"而没有后面的名字。

2.获取初始化参数

(1)

    <!-- 配置一些初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
    </context-param>

(2)

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        String url= (String) context.getAttribute("url");
        response.getWriter().print(url);
    }

请求转发

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext context=this.getServletContext();
        RequestDispatcher requestDispatcher = context.getRequestDispatcher("/demo");//转发的请求路径
        requestDispatcher.forward(request,response);//调用forWord实现请求转发
        //上面两条语句合并就是:
        context.getRequestDispatcher("/demo").forward(request,response);
    }

 4、读取资源文件

Properties:

        在java目录下新建properties

        在resource目录下新建properties

发现:都被打包到了同一个路径:classes,也叫classpath(类路径)

获取这个文件中的数据,需要定义一个流,设置好文件的路径。

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties prop=new Properties();
        prop.load(is);
        String username=prop.getProperty("username");
        String password=prop.getProperty("password");
        response.getWriter().print(username+":"+password);
    }

1.6 HttpServletResponse

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

  •         如果要获取客户端传过来的参数:找HttpServletRequest
  •         如果要给客户端响应一些信息:找HttpServletResponse

1.6.1 简单分类

负责向浏览器发送数据的方法:

ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

负责向浏览器发送响应头方法

    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.6.2 常见应用

        1.向浏览器输出消息

        2.下载文件

  •                 (1)要获取下载文件的路径
  •                 (2)下载的文件名
  •                 (3)设置让浏览器能够支持下载我们需要的东西
  •                 (4)获取下载文件的输入流
  •                 (5)创建缓冲区
  •                 (6)获取OutputStream对象
  •                 (7)将FileOutputStream流写入到buffer缓冲区
  •                 (8)使用OutputStream将缓冲区的数据输出到客户端。
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //(1)要获取下载文件的路径
        String realPath = "D:\\SystemStudy\\LiuStudy\\JavaWebStudy\\responseStudy\\src\\main\\resources\\cookie.jpg";
        System.out.println("下载文件的路径:"+realPath);
        //(2)下载的文件名
        String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
        // (3)设置让浏览器能够支持下载我们需要的东西,中文文件名需要使用URLEncoder编码
        response.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 = response.getOutputStream();
        //(7)将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区的数据输出到客户端。
        while((len = in.read(buffer))>0){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

1.6.3 验证码功能

后端实现:需要用到java图片类,生产一个图片。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //如何让浏览器5秒刷新一次
        response.setHeader("refresh","3");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
        //得到图片
        Graphics2D g = (Graphics2D) image.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);
        //告诉浏览器这个请求用图片的方式打开
        response.setContentType("image/jpeg");
        //网站存在缓存,不让浏览器缓存
        response.setDateHeader("expires",-1);
        response.setHeader("Cache-Control","no-cache");
        response.setHeader("Pragma","no-cache");
        //把图片写给浏览器
        ImageIO.write(image,"jpg",response.getOutputStream());

    }

    //生成随机数
    private String makeNum(){
        Random random = new Random();
        String num = random.nextInt(9999999) + "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 7-num.length(); i++) {
            sb.append("0");
        }
        String s = sb.toString() + num;
        return s;
    }

1.6.4 实现重定向

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

void sendRedirect(String var1) throws IOException;

 测试:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*
             response.setHeader("Location","/responseStudy/image");
             response.setStatus(302);
        */
        //重定向
        response.sendRedirect("/responseStudy/image");
    }

面试题:请你聊聊重定向和转发的区别?

相同点:页面都会实现跳转。

不同点:        

        请求转发的时候,URL不会发生变化。307

        重定向的时候,地址栏会发生变化。302

       

1.7 HttpServletRequest

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

1.7.1 获取前端传来的参数

 ps:解决中文问题的代码,需要写在输出前面,不然会不起作用。

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解决中文乱码问题
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String[] hobbys = request.getParameterValues("hobbys");
        System.out.println("--------------------------------");
        System.out.println(username);
        System.out.println(password);
        System.out.println(Arrays.toString(hobbys));
        System.out.println("--------------------------------");
        //请求转发
        //这里的 / 代表当前的web应用
        request.getRequestDispatcher("/success.jsp").forward(request,response);
    }

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐