笔记代码

分割线

Servlet

请求转发

  • /helloParameter 转发到 /HelloDispatcher

    • 转发后这两个地址都会显示/helloParameter的内容

    • 另外一个手段: 重定向 ,重定向之后原地址就不可访问了


  • src/main/java/com/weidows/HelloDispatcher.java

    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 HelloDispatcher extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    context.getRequestDispatcher("/helloParameter").forward(req, resp);
    }
    }

  • web.xml (在上面初始化参数基础上添加的)

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
    <servlet-name>HelloDispatcher</servlet-name>
    <servlet-class>com.weidows.HelloDispatcher</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>HelloDispatcher</servlet-name>
    <url-pattern>/HelloDispatcher</url-pattern>
    </servlet-mapping>
    </web-app>

读取 properties

我们开发的项目需要进行打包处理,所以不能直接引用 src/ 里面的资源,需要引用对应 target/ 内部的.

  • 这种资源文件一般放在 src/main/resources 里面,如果放在 src/main/java里面默认情况下会出现无法被 maven 导出的情况 (通常我们称 resources 和 java 为 classpath)

    • src/main/java 里面默认情况下只会编译并导出 *.java,不会管其他类型文件,可以修改 pom.xml 来使之生效:

      <build>
      <resources>
      <resource>
      <directory>src/main/java</directory>
      <includes>
      <include>**/*.properties</include>
      <include>**/*.xml</include>
      </includes>
      <filtering>true</filtering>
      </resource>
      </resources>
      </build>

  • 生成文件路径:

    • 如果放在 resources 中,其生成路径为 target/demo-2/WEB-INF/classes/db.properties

    • 如果放在 java 中,生成路径为 target/demo-2/WEB-INF/classes/com/weidows/db.properties


  • 例子: 读取打包后的 properties 并显示.

    • src/main/java/com/weidows/HelloProperties.java

      import java.io.IOException;
      import java.util.Properties;

      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      public class HelloProperties extends HttpServlet {
      /**
      *
      */
      private static final long serialVersionUID = -437042901757770674L;

      @Override
      protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      Properties prop = new Properties();
      // 生成后的路径: target/demo-2/WEB-INF/classes/db.properties
      prop.load(this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"));

      String user = prop.getProperty("username");
      String pwd = prop.getProperty("password");

      resp.getWriter().print("username: " + user + "\npassword: " + pwd);
      }
      }

    • src/main/resources/db.properties

      username=root
      password=123456

    • web.xml

      <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd" >

      <web-app>
      <display-name>Archetype Created Web Application</display-name>

      <servlet>
      <servlet-name>helloProperties</servlet-name>
      <servlet-class>com.weidows.HelloProperties</servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>helloProperties</servlet-name>
      <url-pattern>/helloProperties</url-pattern>
      </servlet-mapping>
      </web-app>

HttpServletResponse

  • Web 服务器接收到 http 请求信息,会创建 HttpServletRequest 和 HttpServletResponse 的两个对象

    • 前者负责客户端传来的参数

    • 后者负责服务端响应的信息


响应

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

    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 varl,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 varl,int var2)

下载文件

  • src/main/java/servlet/FileServlet.java

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.URLEncoder;

    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    public class FileServlet extends HttpServlet {
    /**
    *
    */
    private static final long serialVersionUID = -2643615496012694161L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 要获取下载文件的路径
    String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/test.txt");
    System.out.println("下载文件的路径:" + realPath);

    // 2. 下载的文件名
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    System.out.println("文件名: " + fileName);

    // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
    resp.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 = resp.getOutputStream();

    // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
    while ((len = in.read(buffer)) > 0) {
    out.write(buffer, 0, len);
    }

    // 8. 关闭连接
    in.close();
    out.close();
    }

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

  • src/main/resources/test.txt

    此处内容随意,比如写个 "测试".

  • web.xml

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
    <servlet-name>fileServlet</servlet-name>
    <servlet-class>servlet.FileServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>fileServlet</servlet-name>
    <url-pattern>/fileServlet</url-pattern>
    </servlet-mapping>
    </web-app>

验证码

  • src/main/java/servlet/ImageServlet.java

    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 {

    /**
    *
    */
    private static final long serialVersionUID = 4590298452958016399L;

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

    //如何让浏览器3秒自动刷新一次;
    resp.setHeader("refresh", "3");

    //在内存中创建一个图片
    BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);

    //得到图片
    Graphics2D graphics = (Graphics2D) image.getGraphics(); //笔

    //设置图片的背景颜色
    graphics.setColor(Color.white);
    graphics.fillRect(0, 0, 80, 20);

    //给图片写数据
    graphics.setColor(Color.BLUE);
    graphics.setFont(new Font(null, Font.BOLD, 20));
    graphics.drawString(makeNum(), 0, 20);

    //告诉浏览器,这个请求用图片的方式打开
    resp.setContentType("image/jpeg");

    //网站存在缓存,不让浏览器缓存
    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 num = random.nextInt(9999999) + "";
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < 7 - num.length(); i++) {
    sb.append("0");
    }
    num = sb.toString() + num;
    return num;
    }

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

  • web.xml

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <display-name>Archetype Created Web Application</display-name>
    <servlet>
    <servlet-name>imageServlet</servlet-name>
    <servlet-class>servlet.ImageServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>imageServlet</servlet-name>
    <url-pattern>/imageServlet</url-pattern>
    </servlet-mapping>
    </web-app>

重定向

  • 访问一个页面时跳转到另一个页面

  • src/main/java/servlet/RedirectServlet.java

    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 RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.sendRedirect("/");//重定向
    }

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

  • web.xml

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <servlet>
    <servlet-name>redirect</servlet-name>
    <servlet-class>servlet.RedirectServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>redirect</servlet-name>
    <url-pattern>/redirect</url-pattern>
    </servlet-mapping>
    </web-app>
  • 转发&重定向 の 区别

    • 转发 URL 不会变化,重定向会变化
    • 访问转发的页面有一个请求,重定向会产生前后两个请求,第一个请求状态码是 302

表单提交+响应

Form 表单数据传输方式之 Get 与 Post 区别

  • get 与 post 区别体现在客户端<–>服务端之间的信息传递

  • 我们在 overwrite HttpServlet 类的 doGet & doPost 方法时,是在处理通过 get/post 接收到请求或信息后的业务

  • get/post 就像一个屋子的两个门,进门的方式不一样,但是所进入的屋子是一样的 (让他俩互相调用,处理相同的业务)


  • 例子: 开启 Tomcat 后进入 index.jsp 页面,输入表单后提交,信息以 post 形式传递给 /request 后端,这个动态页面收到数据并在页面输出.

    • index.jsp

      <html>
      <body>
      <form action="/request" method="post">
      <label>
      用户名:
      <input type="text" name="username"/>
      </label> <br/>
      <label>
      密码:
      <input type="password" name="password"/>
      </label> <br/>
      <input type="submit"/>
      </form>
      </body>
      </html>

    • src/main/java/servlet/RequestServlet.java

      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 RequestServlet 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 {
      String username = req.getParameter("username");
      String password = req.getParameter("password");

      PrintWriter writer = resp.getWriter();
      writer.println("Success get username & password.");
      writer.println("username: " + username);
      writer.println("password: " + password);
      }
      }

    • web.xml

      <!DOCTYPE web-app PUBLIC
      "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd" >

      <web-app>
      <display-name>Archetype Created Web Application</display-name>
      <servlet>
      <servlet-name>request</servlet-name>
      <servlet-class>servlet.RequestServlet</servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>request</servlet-name>
      <url-pattern>/request</url-pattern>
      </servlet-mapping>
      </web-app>