详解HttpServlet、HttpServletRequest接口【JAVAEE基础】

1.HTTP协议

 -超文本传输协议
 -浏览器和服务器之间的一种通讯协议
 -W3C制定,本质是提前制定好的数据传送格式。
 包括:
 -请求协议:从Browser发送到Server的时候采用的数据传送格式
    请求行:请求方式 URI 协议版本号
消息报头
空白行:用来分离消息报头和请求体
请求体
 -响应协议:从Server发送到Browser的时候采用的数据传送格式。
    状态行:协议版本号 
响应报头
空白行:分离响应报头和响应体的。
响应体

状态码:
  200:一切正常
  300/301:页面重定向(跳转)
  404:资源不存在(请求的资源路径写错了)
  403:权限不足(如果要访问的目录设置为不可见)
  500:服务器内部错误(代码有误)

2.GET请求和POST请求

--GET请求:除了PSOT请求,都是GET请求
  POST请求:只有当使用from表单,并且将form表单的method属性设置为method="post",才是post请求。

--GET请求和POST请求的区别

   -GET请求在请求行上提交数据:格式uri?name=value&name=value&name=value...
   这种提交方式最终会在浏览器地址栏上显示

   -POST请求在请求体中提交数据,相对安全:提交格式:name=value&name=value&name=value..
   这种提交方式最终不会在浏览器地址栏上显示

   -POST请求在请求体中提交数据,所以POST请求提交的数据没有长度的限制
   -GET请求在请求行上提交数据,所以GET请求提交的数据长度有限制。

   -GET请求只能提交字符串数据,POST请求可以提交任何类型数据,所以文件上传使用POST请求。

   -GET请求最终的结果会被浏览器缓存,POST请求最终的结果不会被浏览器缓存。

--选择使用POST请求的情况(其余的选择GET)
   -有敏感数据。
   -传送数据不是字符串。
   -传送数据非常多
   -这个请求是为了修改服务器端的数据
   
   -GET请求多数情况下是从服务器中读取资源,这个读取的资源在短时间内不会变化,所以浏览器把结果缓存起来了
   -POST请求是为了修改服务器端的资源,而每次修改的结果是不同的,结果没必要缓存。

--浏览器缓存资源,缓存的资源是和某个特定的路径绑定在一起的,只要浏览器再发送中这个相同的路径,
   会去缓存中获取资源,不再访问服务器,提高用户体验。
   如果不希望走缓存,可以在请求路经后添加时间戳,例如:http://ip:port/oa/system/logout?times=5351351435

3.需求:要求前端页面发送的请求方式和服务器端需要的请求方式一致

解决:

 1.在javaweb程序中获取请求方式
   -重点:HTTP的请求协议全部信息被自动封装到javax.servlet.http.HttpServletRequest对象中
 -在HttpServletRequest接口类型中有一个方法:String getMethod();可以获取请求方式
 -public interface javax.servlet.http.HttpServletRequest extends ServletRequest{  }
  
 2.在javaweb程序中进行判断
 if("POST".equals(method)){

 }elseif("GET".equals(method)){
 
 }

4.总结: 在每一个Servlet程序中都编写了以下的程序,来保证前端页面发送的请求方式和服务器端需要的请求方式一致

//将servletRequest,servletResponse强制类型转换成带有http的接口类型
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;

response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取浏览器发送请求的方式
String method = request.getMethod();
if ("GET".equals(method)){
    //前台报错
    out.print("405-应该发送POST请求");
    //后台报错
    throw  new RuntimeException("405-应该发送POST请求");

}else if ("POST".equals(method)){
    out.print("正在登陆");

}

5.封装:HttpServlet

public class HttpServlet extends GenericServlet
{
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		service(request,response);
    }
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String method = request.getMethod();
		if ("GET".equals(method)){
		    doGet(request,response);
		}else if ("POST".equals(method)){
		    doPost(request,response);
		}

    }

    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.print("405-应该发送POST请求");
		throw  new RuntimeException("405-应该发送POST请求");

    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		out.print("405-应该发送GET请求");
		throw  new RuntimeException("405-应该发送GET请求");
    }
}

6.使用HttpServlet重点

   -编写一个Servlet类应该继承javax.servlet.http.HttpServlet,get请求重写doGet方法,post请求重写doPost方法
   -doPost/doGet方法可以等同看作main方法。

   当前端请求方式和后台的处理方式不同的话,会出现405错误。

继承HttpServlet的实现子类

import javax.*;
import java.io.IOException;
import java.io.PrintWriter;

public class LoginServlet extends javax.servlet.http.HttpServlet
{
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        out.println("login......");
    }
    //复写doPost方法,如果前段发送的doGet请求,会调用父类中的doGet方法,报错。

}

7.HttpServletRequest接口:

  1.javax.servlet.http.HttpServletRequest 是一个接口,Servlet规范重要接口之一。
  2.继承关系:
      public interface HttpServletRequest extends ServletRequest;
      
  3.HttpServletRequest接口的实现类是Web容器实现的,面向接口调用方法即可。
  
  4.封装了HTTP请求协议的全部内容:
      -请求方式
	  -URI
	  -版本协议号
	  -表单提交的数据
	  ...

5.HttpServletRequest一般变量叫做:request,一次请求对应一个request对象。

 所以request对象的生命周期是短暂的。
 一次请求:网页上点击超链接,到页面停下来,看作是一次完整的请求。
 举例:点击A连接,执行向request范围中存入一个对象,点击B连接从request范围中获取这个对象,是获取不到的。

6.HttpServletRequest中常用的方法

 -表单提交的数据会被自动封装到request对象中,request对象中有map集合存储请求数据
 - Map<String,String[]>   
-String getParameter(String name) //通过key获取value一维数组中的首元素(最常用)
-Map getParameterMap()     //获取整个Map集合
-Enumeration getParameterNames()   //获取整个map集合的所有key
-String[] getParameterValues(String name)   //通过Map集合的key获取value

-String getContextPath()       //获取webapp的根路径【上下文路径】
-String getMethod()            //获取浏览器的请求方式
-String getRequestURI()        //获取请求的URI
-StringBuffer getRequestURL()  //获取请求的URL
-String getServletPath()       //获取Servlet Path 【url-pattern】
-String getRemoteAddr()        //获取客户端IP地址


-void setAttribute(String name,Object o)  //向request范围中存储数据
-Object getAttribute(String name)         //从request范围中读取数据
-void removeAttribute(String name)        //移除request范围中的数据
//request范围代表同一次完整的请求。

-Cookie[] getCppkies()      //获取Cookie对象
-HttpSession getSession()    //获取Session对象

如何将AServlet和BServlet执行放在同一个请求中

-RequestDispatcher getRequestDispatcher(String path)  //获取请求转发器,指向转发的路径

//使用转发技术 forward【转发是一次请求】
//1.获取请求转发器对象
//RequestDispathcer dispathcher = request.getRequestDispatcher("/b");//指向BServlet
//2.调用转发器的forward方法即可完成转发
//dispathcher.forward(request,response);
//合并: request.getRequestDispatcher("/b").forward(request,response);

-void setCharacterEncoding(String env)

7.关于范围对象的选择:

ServletContext  应用范围,可以跨用户传递数据
ServletRequest  请求范围,只能在同一个请求中传递数据【可以跨Servlet传递数据,但是Servlet必须在同一个请求中】
优先选择request范围。

使用HttpServletRequest中的方法实现获取前台用户输入的数据

项目结构
在这里插入图片描述
register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>register</title>
</head>
<body>
    <form action="/prj_servlet_09_war_exploded/user/save" method="post">
        用户名<input type="text" name="username">
        <br>
        密码<input type="text" name="password">
        <br>
        性别
           男<input type="radio" name="sex" value="m"><input type="radio" name="sex" value="f">
        <br>
        爱好
           <input type="checkbox" name="interset" value="sport">运动
           <input type="checkbox" name="interset" value="music">音乐
           <input type="checkbox" name="interset" value="dance">跳舞
           <input type="checkbox" name="interset" value="study">学习
           <input type="checkbox" name="interset" value="read">阅读
        <br>
        学历
          <select name="grade">
              <option value="gz" >高中</option>
              <option value="dz" >专科</option>
              <option value="db" >本科</option>
          </select>
        <br>
        简介
           <textarea rows="10" cols="60" name="introduce"></textarea>
        <br>
        <input type="submit" value="注册">
        <input type="reset" value="重置">
    </form>

</body>
</html>

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">
    <welcome-file-list>
        <welcome-file>register.html</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>save</servlet-name>
        <servlet-class>com.chif.SaveUserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>save</servlet-name>
        <url-pattern>/user/save</url-pattern>
    </servlet-mapping>
</web-app>

SaveUserServlet.java

package com.chif;

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;
import java.util.Map;
import java.util.Set;

public class SaveUserServlet extends HttpServlet
{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取用户信息、
        //从request中获取
        String username = req.getParameter("username");
        String password=req.getParameter("password");
        String sex = req.getParameter("sex");
        //String interset = req.getParameter("interset");
        String grade = req.getParameter("grade");
        String introduce = req.getParameter("introduce");

        //获取所有的兴趣爱好
        String[] intersets = req.getParameterValues("interset");

        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        System.out.println(username);
        System.out.println(password);
        System.out.println(sex);
        for (String in:intersets){
            System.out.println(in);
        }
        System.out.println(grade);
        System.out.println(introduce);


        //第二种方法:获取整个map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        Set<String> names = parameterMap.keySet();
        for (String name:names){
            String[] values = parameterMap.get(name);
            System.out.print(name+"=");
            for (String value:values){
                System.out.println(value);
            }

        }


    }
}

运行截图:
前台
前台
后台输出获取结果

username=zhangsan
password=123
sex=m
intersets=sport music dance study read
grade=db
introduce=I like somkeing!

15.模版方法设计模式

  。。。。。。。
  典型应用:Servlet规范中的HttpServlet
      HttpServlet是一个模版类
  其中的service(HttpServletRequest,HttpServletResponse)方法是典型的模板方法
  doGet,doPost...具体的实现步骤延迟到子类中去完成.
   模版方法设计模式的特点:
     doXXX
     doYYY
     doZZZ
   模版方法设计模式的主要作用
      1.核心算法得到保护
      2.核心算法得到复用
      3.在不改变算法的前提下,可以重新定义算法步骤的具体实现。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值