Servlet:HelloServlet入门程序;Mapping配置;ServletContext;Response

Servlet

1、Servlet简介

  • Servlet (Service Applet) 是在服务器上运行的小程序。
  • 广义的Servlet是指任何实现了这个Servlet接口的类Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器

2、HelloServlet

  • Java提供了两个默认的Servlet接口实现类:
    • HttpServlet
    • GenericServlet
  1. 构建一个普通的Maven项目,删掉里面的src目录,以后我们的学习就在这个项目里面建立Moudel,这个空的工程就是Maven主工程

    • Maven父子工程

      父项目中会有

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

      子项目会有

          <parent>
              <artifactId>javaweb</artifactId>
              <groupId>com.study</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
      
  2. 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"
               metadata-complete="true">
      </web-app>
      
    2. 将maven的结构搭建完整

      创建 javaresources 文件夹

  3. 编写一个Servlet程序
    在这里插入图片描述

  • 定义一个类,实现Servlet接口,这里我们直接继承HttpServlet

    public class HelloServlet extends HttpServlet {
    //由于get和post只是请求的不同的方式,所以doGet和doPost业务逻辑都一样,可以相互调用
        @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 {
            doGet(req, resp);
        }
    }
    
  1. 编写Servlet的映射

    <!--注册Servlet-->
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.study.servlet.HelloServlet</servlet-class>
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
  2. 配置Tomcat服务器

  3. 启动发布

3、Servlet原理

在这里插入图片描述

4、Mapping配置

  • 一个Servlet可以指定一个映射路径
	<servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
  • 一个Servlet可以指定多个映射路径
	<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>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello3</url-pattern>
    </servlet-mapping>
  • 一个Servlet可以指定通配的映射路径
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <!-- * 通配任意字符串-->
        <url-pattern>/hello/*</url-pattern>
    </servlet-mapping>
  • 默认请求路径
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
  • 指定后缀或前缀等
<!--
   注意点,*前面不能加项目映射的路径
-->
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>*.study</url-pattern>
</servlet-mapping>
  • 优先级问题:指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求

5、ServletContext

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

5.1、共享数据

  • 即在一个Servlet中保存的数据,可以在另外一个servlet中拿到
public class HelloServlet extends HttpServlet {
	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = "张三"; //数据
        //将一个数据保存在了ServletContext中,字段名:username 值 “张三”
        context.setAttribute("username",username); 
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 获取保存在ServletContext中的数据
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.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.study.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.study.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>getc</servlet-name>
    <url-pattern>/getc</url-pattern>
</servlet-mapping>
  • 测试访问

    • 若直接访问 http://localhost:8080/s2/getc ,由于username还未赋值,所以username=null;
      在这里插入图片描述

    • 先访问 http://localhost:8080/s2/hello ,将数据存进ServletContext

    • 再访问 http://localhost:8080/s2/getc
      在这里插入图片描述

5.2、获取初始化参数

    <!--配置一些web应用初始化参数-->
    <context-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/mydb</param-value>
    </context-param>
public class TestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String url = context.getInitParameter("url");
        resp.getWriter().print(url);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 测试访问:
    在这里插入图片描述

5.3、请求转发

public class ForwardServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        // "/url" 5.2中的Servlet
        context.getRequestDispatcher("/url").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 测试访问:
    在这里插入图片描述
  • 转发过程:
    在这里插入图片描述

5.4、读取资源文件

  • 在java目录下新建properties文件

  • 在resources目录下新建properties文件

  • 发现:都被打包到了同一个路径下:classes/ ,我们俗称这个路径为classpath

  • maven由于他的约定大于配置,可能出现配置文件无法被导出或者生效的问题,解决方案:

<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
  • prop.properties
username=root
password=123456
  • PropServlet.java
public class PropServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = getServletContext();
        InputStream resourceAsStream = context.getResourceAsStream("WEB-INF/classes/prop.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        resp.getWriter().print("<h1>"+username+"==="+password+"</h1>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 测试访问:
    在这里插入图片描述

6、Response

6.1、浏览器下载文件

public class FileDownloadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //需要下载的文件在服务器的路径
        String filePath="D:\\IdeaProjects\\maven-javaweb-01\\Servlet-03\\src\\main\\resources\\背景.png";
        //文件名
        String fileName=filePath.substring(filePath.lastIndexOf('\\')+1);
        //设置使浏览器能够支持下载(Content-Disposition)我们需要的东西,中文文件名需要设置编码(URLEncoder.encode),否则有可能乱码
        resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
        //创建读取文件的输入流
        FileInputStream in = new FileInputStream(filePath);
        //获取输出流
        ServletOutputStream out =resp.getOutputStream();
        //创建buffer缓冲区
        byte[] buffer = new byte[1024 * 8];
        int len=0;
        //将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到浏览器!
        while ((len=in.read(buffer))!=-1){
            out.write(buffer,0,len);
        }
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 测试访问:
    在这里插入图片描述

6.2、创建一张图片,在其中生成8位随机数,并响应给浏览器

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //让浏览器3秒自动刷新一次
        resp.setHeader("refresh","3");
        //在内存中创建一个图片
        BufferedImage image = new BufferedImage(200, 40, BufferedImage.TYPE_INT_RGB);
        //获取图片
        Graphics2D g = (Graphics2D) image.getGraphics();
        //设置图片背景颜色
        g.setColor(Color.cyan);
        g.fillRect(0,0,200,40);
        //在图片中写入数据
        g.setColor(Color.RED);
        g.setFont(new Font("华文彩云",Font.BOLD,30));
        g.drawString(getNum(),20,30);
        //把图片写到浏览器
        ImageIO.write(image,"png",resp.getOutputStream());
    }

    private String getNum() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(random.nextInt(99999999));
        int sbLen=sb.length();
        for (int i = 0; i < 8-sbLen; i++) {
            sb.append(random.nextInt(10));
        }
        return sb.toString();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 测试访问:
    在这里插入图片描述

6.3、重定向

  • RedirectServlet.java
public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //重定向
        resp.sendRedirect("/s3/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>success</title>
</head>
<body>
<h1>redirect success!</h1>
</body>
</html>
  • 测试访问:
    在这里插入图片描述

  • 重定向示意图:
    在这里插入图片描述

  • 重定向和转发的区别:

    • 重定向是两次请求,转发是一次请求,因此转发的速度要快于重定向;

    • 重定向之后地址栏上的地址会发生变化,变化成第二次请求的地址,转发之后地址栏上的地址不变,还是第一次请求的地址;

    • 转发是服务器行为,重定向是客户端行为;

    • 重定向时的网址可以是任何网址,转发的网址必须是本站点的网址。

发布了55 篇原创文章 · 获赞 23 · 访问量 4332

猜你喜欢

转载自blog.csdn.net/y_Engineer/article/details/100776850