JavaWeb学习(二)之HTTP Servlet

JavaWeb学习(二)之HTTP Servlet

推荐视频 B站:遇见狂神说JavaWeb视频:https://www.bilibili.com/video/BV12J411M7Sj

1、HTTP

1.1、什么是HTTP

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

简单来说http就是一个简单的请求-响应协议。

工作原理如下

  • HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

  • Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。

  • Web服务器根据接收到的请求后,向客户端发送响应信息。

  • HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

1.2、HTTP请求

客户端—发请求(Request)—服务器

在这里插入图片描述

菜鸟教程

例如360导航:

请求 URL: https://hao.360.com/    请求地址
请求方法: GET					   get方法/post方法
状态代码: 200 / OK                 状态码:200

在这里插入图片描述

1.3、请求行

  • 请求行中的请求方式:GET
  • 请求方式:Get,Post,HEAD,DELETE,PUT,TRACT…
    • get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
    • post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。

1.4、消息头

Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.

1.5、Http响应

  • 服务器—响应-----客户端

百度:

Cache-Control:private    缓存控制
Connection:Keep-Alive    连接
Content-Encoding:gzip    编码
Content-Type:text/html   类型
1.5.1、响应体
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式  GBK   UTF-8   GB2312  ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成是断开还是保持连接
HOST:主机..../.
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位;
1.5.2、响应状态码

在这里插入图片描述

200:请求响应成功 200

3xx:请求重定向

  • 重定向:你重新到我给你新位置去;

4xx:找不到资源 404

  • 资源不存在;

5xx:服务器代码错误 500 502:网关错误

2、Servlet

2.1、什么是servlet

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。我们可以这样理解Servlet是指Java语言实现的一个接口或者是实现了这个Servlet接口的类

2.2、第一个Servlet程序

第一步在 IDEA或者eclipse中创建一个web项目 这里以IDEA为例 下面提供两种创建web项目的方法

  1. 用Maven创建一个web项目 官网:https://maven.apache.org/ 在网上可以自己找教程下载配置maven

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

maven目录结构
在这里插入图片描述

项目建好后目录结构
在这里插入图片描述

2.用普通方法创建web项目
在这里插入图片描述

然后就在java目录下创建一个普通类 继承HttpServlet

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet方法开始启动");
        PrintWriter writer = resp.getWriter();
        writer.print("Hello world ----helloServlet");
    }

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

然后在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">
    <!--注册Servlet-->
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.song.servlet.HelloServlet</servlet-class> 继承HttpServlet类的路径
    </servlet>
    <!--Servlet的请求路径-->
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/helloservlet</url-pattern>
    </servlet-mapping>
</web-app>

然后就是index.jsp页面 里面的是前端的内容给用户看的 可以自己随便写

<html>
<body>
<h2>Hello World!</h2>
</body>
</html>

然后就是配置Tomact 若不会可以自己网上查

配置好后就可以启动呢

在这里插入图片描述

在这里插入图片描述

2.3、Servlet原理

Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:
在这里插入图片描述

2.4、ServletContext

​ 一个web应用对应一个ServletContext,所以ServletContext的作用范围是整个应用,也就是说web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用 ;

在这里插入图片描述

来自于百度百科的图 这里先不用管Cookie和Session

  1. ServletContext的作用是什么

    作为域对象使用。

    初始化参数。

    请求转发。

    读取资源文件。

  2. 共享数据

    在A Servlet中保存数据 ,可以在B Servelt中获取A 当中存放在ServletContex中数据

    //A Servlet
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //servlet上下文
            ServletContext servletContext = this.getServletContext();
            String username = "SC";
            //将一个数据保存在servletContext中 名字为username 值为username
            servletContext.setAttribute("username",username);
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req,resp);
        }
    }
    //B Servlet 
    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);
        }
    }
    <?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">
      <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.song.servlet.HelloServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/helloservlet</url-pattern>
      </servlet-mapping>
      
      <servlet>
        <servlet-name>getServlet</servlet-name>
        <servlet-class>com.song.servlet.GetServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>getServlet</servlet-name>
        <url-pattern>/getservlet</url-pattern>
      </servlet-mapping>
    </web-app>
  3. 获取初始化参数

      <!--配置一些web应用初始化参数-->
        <context-param>
            <param-name>name</param-name>
            <param-value>vaule</param-value> 
        </context-param>
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext(); //可以使用getServeltContext获取这个name 在配置中写的
        String name = context.getInitParameter("name");
        resp.getWriter().print(name);
    }
  4. 请求转发

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        System.out.println("HelloServelt2");
        //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/helloServelt"); //转发的请求路径
        //requestDispatcher.forward(req,resp); //调用forward实现请求转发;
        context.getRequestDispatcher("/helloServelt").forward(req,resp);
    }
  5. 读取资源文件

    假如说在你的javaweb项目中的resources中有一个properties 里面配置这一些属性 这时 我们可以通过ServletContext读取这个文件

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

2.5、HttpServletResponse

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

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

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

    以下为 HttpServletResponse 对象可以调用的方法 不要求全部掌握 若想详细了解这些方法 可以看菜鸡教程 以下表格方法引用于菜鸟教程

1 String encodeRedirectURL(String url)
为 sendRedirect 方法中使用的指定的 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
2 String encodeURL(String url)
对包含 session 会话 ID 的指定 URL 进行编码,或者如果编码不是必需的,则返回 URL 未改变。
3 boolean containsHeader(String name)
返回一个布尔值,指示是否已经设置已命名的响应报头。
4 boolean isCommitted()
返回一个布尔值,指示响应是否已经提交。
5 void addCookie(Cookie cookie)
把指定的 cookie 添加到响应。
6 void addDateHeader(String name, long date)
添加一个带有给定的名称和日期值的响应报头。
7 void addHeader(String name, String value)
添加一个带有给定的名称和值的响应报头。
8 void addIntHeader(String name, int value)
添加一个带有给定的名称和整数值的响应报头。
9 void flushBuffer()
强制任何在缓冲区中的内容被写入到客户端。
10 void reset()
清除缓冲区中存在的任何数据,包括状态码和头。
11 void resetBuffer()
清除响应中基础缓冲区的内容,不清除状态码和头。
12 void sendError(int sc)
使用指定的状态码发送错误响应到客户端,并清除缓冲区。
13 void sendError(int sc, String msg)
使用指定的状态发送错误响应到客户端。
14 void sendRedirect(String location)
使用指定的重定向位置 URL 发送临时重定向响应到客户端。
15 void setBufferSize(int size)
为响应主体设置首选的缓冲区大小。
16 void setCharacterEncoding(String charset)
设置被发送到客户端的响应的字符编码(MIME 字符集)例如,UTF-8。
17 void setContentLength(int len)
设置在 HTTP Servlet 响应中的内容主体的长度,该方法设置 HTTP Content-Length 头。
18 void setContentType(String type)
如果响应还未被提交,设置被发送到客户端的响应的内容类型。
19 void setDateHeader(String name, long date)
设置一个带有给定的名称和日期值的响应报头。
20 void setHeader(String name, String value)
设置一个带有给定的名称和值的响应报头。
21 void setIntHeader(String name, int value)
设置一个带有给定的名称和整数值的响应报头
22 void setLocale(Locale loc)
如果响应还未被提交,设置响应的区域
23 void setStatus(int sc)
为该响应设置状态码。

响应的状态码 建议去看菜鸟教程 自己去查找

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

  2. 下载的文件名是啥?

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

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

  5. 创建缓冲区

  6. 获取OutputStream对象

  7. 将FileOutputStream流写入到buffer缓冲区

  8. 使用OutputStream将缓冲区中的数据输出到客户端!

    public class DownServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 1. 要获取下载文件的路径
            String realPath = "D:\\Java练习\\JavaWeb\\Javaweb-02-servlet\\response\\src\\main\\resources\\张三.png";
            // 2. 下载的文件名是啥?
            String sub = realPath.substring(realPath.lastIndexOf("\\") + 1);
            // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
            resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(sub,"UTF-8"));
            // 4. 获取下载文件的输入流
            FileInputStream in = new FileInputStream(realPath);
            // 5. 创建缓冲区
            int len = 0 ;
            byte buffer[] = new byte[1024];
            // 6. 获取OutputStream对象
            ServletOutputStream outputStream = resp.getOutputStream();
            // 7. 将FileOutputStream流写入到buffer缓冲区 8. 使用OutputStream将缓冲区中的数据输出到客户端!
            while ((len = in.read(buffer))!=-1){
                outputStream.write(buffer,0,len);
            }
            //9 . 关闭流资源
            in.close();
            outputStream.close();
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
2.5.2、实现重定向
response.sendRedirect(url)使用指定的重定向位置 URL 发送临时重定向响应到客户端。

简单实现登录重定向

<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
</form>
   @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username"); //通过getParameter获取前端表单的name和password
        String password = req.getParameter("password");
        resp.sendRedirect("/success.jsp"); //自己去写个success.jsp并且配置。。。注意路径问题 不要错呢
    }

重定向和转发的区别?

相同点

  • 页面都会实现跳转

不同点

  • 请求转发的时候,url不会产生变化
  • 重定向时候,url地址栏会发生变化;

2.6 、HttpServletRequest

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

HttpServletRequest对象可以调用的相关方法 去看菜鸟教程 这里就不写呢 菜鸟教程

获取参数,请求转发

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

    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");
    System.out.println(req.getContextPath());
    //通过请求转发
    //这里的 / 代表当前的web应用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}

获取参数,请求转发

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

    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");
    System.out.println(req.getContextPath());
    //通过请求转发
    //这里的 / 代表当前的web应用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}

如有错误 欢迎纠正哦

猜你喜欢

转载自blog.csdn.net/qq_44763720/article/details/107486019