菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
326
0

Servlet

原创
05/13 14:22
阅读数 37008

1.1 servlet简介

  • servlet简介就是sun公司开发动态web的一门技术。

  • sun在这些API中提供一个接口叫作:servlet,如果你想开发一个servlet程序,只需要完成两个小步骤:

    • 编写一个类,实现servlet接口。

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

把实现了servlet接口的Java程序叫做servlet。

 


1.2 HelloServlet

1.先建一个空的父工程项目,随后再建有模板的前端子模块工程。

2.修改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">
     <display-name>Archetype Created Web Application</display-name>
 </web-app>

3.建servlet类

 package com.lihui;
 ​
 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 {
         System.out.println("欢迎进入Servlet学习!");
         PrintWriter writer = resp.getWriter();
         writer.println("Hello Servlet!");
     }
 ​
     @Override
     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         doGet(req, resp);
     }
 }

 

4.在web.xml文件里写Servlet的映射

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

<?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">
 ​
     <servlet>
         <servlet-name>HelloServlet</servlet-name>
         <servlet-class>com.lihui.HelloServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>HelloServlet</servlet-name>
         <url-pattern>/hello</url-pattern>
     </servlet-mapping>
 </web-app>

5.配置tomcat

先将项目打成war包,才能部署在tomcat上。

6.运行项目。

 


1.3 servlet原理

servlet是由web服务器调用,web服务器在收到浏览器请求之后的流程:

核心:调用servlet里面的service方法,重写里面的resq和resp方法。

 


1.4 mapping问题

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

     <servlet>
         <servlet-name>HelloServlet</servlet-name>
         <servlet-class>com.lihui.HelloServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>HelloServlet</servlet-name>
         <url-pattern>/hello</url-pattern>
    </servlet-mapping>
  1. 一个servlet可以指定多个映射路径。

     <servlet>
         <servlet-name>HelloServlet</servlet-name>
         <servlet-class>com.lihui.HelloServlet</servlet-class>
     </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>
     <servlet-mapping>
         <servlet-name>HelloServlet</servlet-name>
         <url-pattern>/hello3</url-pattern>
     </servlet-mapping>
  1. 一个servlet可以指定通用映射路径。

    <servlet>
         <servlet-name>HelloServlet</servlet-name>
         <servlet-class>com.lihui.HelloServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>HelloServlet</servlet-name>
         <url-pattern>/*</url-pattern>
     </servlet-mapping> 
  1. 指定一些后缀或者前缀等等。

    <servlet>
         <servlet-name>HelloServlet</servlet-name>
         <servlet-class>com.lihui.HelloServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>HelloServlet</servlet-name>
         <!--注意:*前面不能带/-->
         <url-pattern>*.lihui</url-pattern>
     </servlet-mapping>

  


1.5 ServletContext

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

即:同一个web应用里的所有servlet共用一个ServletContext。

共享数据

 @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         System.out.println("欢迎进入Servlet学习!");
         PrintWriter writer = resp.getWriter();
         writer.println("Hello Servlet!");
 ​
         ServletContext servletContext = this.getServletContext();
         String username = "李慧";
         servletContext.setAttribute("username", username);
     }
     
   @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         resp.setContentType("text/html");
         resp.setCharacterEncoding("utf-8");
         ServletContext servletContext = this.getServletContext();
         String username = (String) servletContext.getAttribute("username");
         resp.getWriter().println("我的名字"+username);
     }
     
     <servlet>
         <servlet-name>getc</servlet-name>
         <servlet-class>com.lihui.GetSC</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>getc</servlet-name>
         <url-pattern>/getc</url-pattern>
     </servlet-mapping> 
 注意:要先运行/hello,先把数据放入ServletContext里面,随后运行/getc,才能渠道数据,不然取出来的是null。

获取初始化参数

 @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {       
         ServletContext servletContext = this.getServletContext();
         String url = servletContext.getInitParameter("url");
         resp.getWriter().println(url);
     }
     
     
 web.xml
     <context-param>
         <param-name>url</param-name>
         <param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
     </context-param>

请求转发

    ServletContext servletContext = this.getServletContext();
      servletContext.getRequestDispatcher("/getc").forward(req,resp);

请求转发的url路径不变,重定向路径改变。

关键是调用里面的额forward方法。

读取资源文件

Properties

  • 在Java目录下新建properties。这个需要在web.xml文件里添加build过滤,不然导出不了。

  • 在resources目录下新建properties。

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

思路:需要一个文件流。

 # 输入流InputStream 对象以流的方式getResourceAsStream 读取文件,写好文件所在的位置
 InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
 # Properties 对象使用load()方法载入流文件
 Properties properties = new Properties();
 properties.load(is);
 # getProperties得到文件的属性。
 String user = properties.getProperty("username");
 String pwd = properties.getProperty("password");
 # 在页面上打印出来
 resp.getWriter().println(user+":"+pwd);

1.6 HttpServletResponse

本质上,web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,和一个代表响应的HttpServletResponse对象。

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

  • 如果要给客户端响应一些信息:找HttpServletResponse.

1.简单分类

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

public ServletOutputStream getOutputStream() throws IOException;
     ### Returns a ServletOutputStream suitable for writing binary data in the response. The servlet container does not encode the binary data.
   
   
   public PrintWriter getWriter() throws IOException;
     ### Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding. If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

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

public void setCharacterEncoding(String charset);    #("utf-8")
 ​
 public void setContentLength(int len);      
 ​
 public void setContentLengthLong(long len);
 ​
 public void setContentType(String type);    #("text/html")
 ​
 public void setBufferSize(int size);
 ​
 public int getBufferSize();

2.常见应用

1.向浏览器输出消息

 getWrite();
 ​
 getOutputStream();

2.下载文件

  1. 要获取下载文件的路径。

  2. 下载的文件名是啥。

  3. 设置想办法让浏览器能够支持下载我们需要的文件。

  4. 获取下载文件的输入流。

  5. 创建缓冲区。

  6. 获取OutputStream对象。

  7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端。

//        1. 要获取下载文件的路径。
         String realPath = "D:\\第四阶段-Javaweb\\javaweb-servlet\\http-response\\target\\classes\\1.jpg";
 //        2. 下载的文件名是啥。
         System.out.println("下载文件的真实路径:"+realPath);
         String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
 //        3. 设置想办法让浏览器能够支持下载我们需要的文件。
         resp.setHeader("Content-Disposition","attachment;filename"+fileName);
 //        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);
         }
         in.close();
         out.close();
     }

3.Response验证码功能

单独一个模块。

4.实现重定向

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

常见场景:

  • 用户登录。

 resp.sendRedirect("");

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

相同点:

  • 页面都会实现跳转。

不同点:

  • 请求转发的时候,url不会产生变化。

  • 重定向的时候,url会发生变化。

1.7 HttpServletRequest

1、获取前端请求参数。

 req.getParameter("");   #获取单个
 String username = req.getParameter("username");
 ​
 req.getParameterValues(""); #获取多个
 string[] hobbys = req.getParameterValues("hobbys");

2、请求转发。

req.getRequestDispatcher("/success.jsp").forword(req,resp);

  

 

 

发表评论

0/200
326 点赞
0 评论
收藏