JavaWeb-Request讲解

1. Request概述

2. reuqest获取请求消息内容
    请求行
    请求头
    请求参数(体)
3. request其他功能
    请求转发
    域对象

一.Request概述:

- 用户通过浏览器访问服务器时,Tomcat将HTTP请求中所有的信息都封装在Request对象中
- 作用:开发人员可以通过request对象方法,来获取浏览器发送的所有信息.

JavaWeb-Request讲解_第1张图片

Web 服务器收到客户端的 http 请求,会针对每一次请求
分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。

Request的体系结构

JavaWeb-Request讲解_第2张图片

JavaWeb-Request讲解_第3张图片

javax.servlet.http.HttpServletReuqest不是相关请求的顶级接口,它继承自 父接口javax.servlet.ServletRequest:

JavaWeb-Request讲解_第4张图片

上图为继承关系:
 
HttpServletRequest 对象代表客户端的请求,当客户端通过 HTTP 协议访问服务器时, HTTP 请求中的所有信
息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
 

在javaEE中我们是面向接口编程

JavaWeb-Request讲解_第5张图片

通过以上分析:Request对象进行常用的操作为:

1) 获取请求数据
2)作为域对象
3)请求转发

二 Request获取Http请求信息

Api介绍

String getMethod() 获取请求方式的类型 如:GET或POST 
StringBuffer getRequestURL() 获取客户端发出请求完整URL 
String getRequestURI() 获取请求行中的资源名部分 
String getContextPath() 获取当前项目根路径 
String getProtocol() 获取当前协议的名称和版本 
String getRemoteAddr() 获取IP地址 
int getLocalPort() 获取端口
注:
uri: 统一资源标识符 , 用来标识一个资源 , 资源路径。 ( 相当于身份证 )
url: 统一资源定位符 , 是一种具体的 URI, 可以用来标识一个资源 . 并且指明了如何定位一个资源(相当于身份证的地址)
如:
http://localhost:8080/wsl/demo
url: http://localhost:8080/wsl/demo
uri: /wsl/demo

1。获取请求行信息

* 例如:
		GET /wsl_request/requestDemo1 HTTP/1.1

* 相关API:
	1. 获取请求方式 GET
			String getMethod()  
			
	2. 获取项目虚拟路径(项目名)/wsl_request
			String getContextPath()
			
	3. 获取URI /wsl_request/requestDemo1
			统一资源标识符(范围广)  共和国
			String getRequestURI() 
			
	4. 获取URL http://localhost:8080/wsl_request/requestDemo1
			统一资源定位符(确定某一个地址) 中华人民共和国
			StringBuffer getRequestURL()  
			
	5. 获取协议和版本号	HTTP/1.1
			String getProtocol()
			
	6. 获取客户端ip
			String getRemoteAddr()
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // System.out.println(req);
        System.out.println("请求方式:" + req.getMethod());
        System.out.println("虚拟路径:" + req.getContextPath());
        System.out.println("URI:" + req.getRequestURI());
        System.out.println("URL:" + req.getRequestURL());
        System.out.println("协议和版本:" + req.getProtocol());
        System.out.println("客户端ip:" + req.getRemoteAddr());

    }

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

    }
}

2.获取请求头信息

* 例如:
        Host: localhost:8080
        
* 相关API:
    1. 获取知道请求头名称对应的值,注:名称不区分大小写
            String getHeader(String name)  
            
    2. 获取所有请求头的名称
            Enumeration getHeaderNames()  
            注:是Iterator前身

@WebServlet("/requestDemo2")
public class RequestDemo2 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取所有的请求头名称
        Enumeration enumeration = req.getHeaderNames();
        // 遍历
        while(enumeration.hasMoreElements()){
            // 取出元素名(请求头名称)
            String name = enumeration.nextElement();
            // 根据名称获取值
            String value = req.getHeader(name);
            System.out.println(name +" : "+ value);
        }
    }

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

    }
}

3.demo

请求头中参数有一个referer:请求来源

/*
    视频防盗链
 */
@WebServlet("/refererRequest")
public class RefererRequest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        // 1.获取请求来源(如果是浏览器地址直接访问的话,referer就是null)
        String referer = req.getHeader("referer");
        // 2.判断是不是自家网站发起的请求
        if (referer != null && referer.startsWith("http://localhost:8080")) {
            resp.getWriter().write("正常播放视频...");
        }else{
            resp.getWriter().write("想看吗?来优酷吧....");
        }
    }

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

    }
}

4.浏览器兼容性问题

user-agen:浏览器版本信息

JavaWeb-Request讲解_第6张图片

/*
    浏览器兼容性
 */
@WebServlet("/userAgentReqeust")
public class UserAgentReqeust extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");

        // 1.获取浏览器版本信息
        String userAgent = req.getHeader("user-agent");
        // 2.判断浏览器版本
        if (userAgent.contains("Chrome")) {
            resp.getWriter().write("浏览器:谷歌");
        } else if (userAgent.contains("Firefox")) {
            resp.getWriter().write("浏览器:火狐");
        } else {
            resp.getWriter().write("浏览器:其他");
        }
    }

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

    }
}

5.获取请求参数,请求体

  • 不论get还是post请求方式,都可以使用下列方法来获取请求参数

  • 在web阶段,get和post处理的业务逻辑都是一样的

* 参数
		username=wsl&password=123456&hobby=eat&hobby=perm
		
* API
	1. 获取指定参数名的值  username=wsl
			String getParameter(String name)
			
	2. 获取指定参数名的值数组  hobby=eat&hobby=perm
			String[] getParameterValues(String name)
	
	3. 获取所有参数名和对应值数组,参数名 name(key),值数组 value,封装map集合
			Map getParameterMap()
			
			
* 中文乱码【重点】
	get:在tomcat8及以上版本,内部URL编码(UTF-8)
	post:编码解码不一致,造成乱码现象
		客户端(浏览器)编码:UTF-8
		服务器默认     解码:ISO-8859-1 拉丁文
		指定解码:void setCharacterEncoding(String env)
			注:必须在方法内,行首



    
    form



get方式:

用户:
密码:
爱好: 烫头

post方式:

用户:
密码:
爱好: 烫头
@WebServlet("/requestDemo3")
public class RequestDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("手动获取---------");
        String username = req.getParameter("username");
        System.out.println("用户:" + username);
        String password = req.getParameter("password");
        System.out.println("密码:" + password);
        String[] hobby = req.getParameterValues("hobby");
        System.out.println("爱好:" + Arrays.toString(hobby));
        System.out.println("自动获取---------");
        Map parameterMap = req.getParameterMap();
        parameterMap.forEach((k, v) -> { //此处用了lamda表达式
            System.out.println(k + " = " + Arrays.toString(v));
        });
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 指定post的解码方式....
        req.setCharacterEncoding("UTF-8");
        System.out.println("post提交方法,再去调用get....");
        this.doGet(req, resp); 

    }
}

6.BeanUtils jar包

  • 是apache组织,提供一套工具类,简化参数的封装.....

  • 简单来说:将前端提交的数据,直接封装到你想要的JavaBean中

 (1)向项目中导入jar包

JavaWeb-Request讲解_第7张图片

(2)使用工具类封装数据

BeanUtils测试:

用户:
密码:
爱好: 烫头

(3)数据封装:

@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    // 使用BeanUtils快速封装数据到 User对象中
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");// 指定解码方式
        // 1.获取所有参数的数据,map集合
        Map parameterMap = request.getParameterMap();
        // 2.创建user对象
        User user = new User();
        // 3.调用工具类,实现快速封装
        try {
            BeanUtils.populate(user, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(user);
    }

}

考虑问题:

JavaWeb-Request讲解_第8张图片

 

三Request其他功能

1.请求转发

一种在服务器内部的资源跳转方式

JavaWeb-Request讲解_第9张图片

* API
    1. 通过reqeust对象,获得转发器对象
            RequestDispatcher getRequestDispatcher(String path)
            
    2. 通过转发器对象,实现转发功能
            void forward(ServletRequest request, ServletResponse response)  
            
* 请求转发特点
    浏览器:发了一次请求
    地址栏:没有发生改变
    只能转发到服务器内部资源....
    
* 链式编程
        request.getRequestDispatcher("/bServlet").forward(reqeust,response)

2.域对象,(共享数据)

- 域对象:一个有作用范围的对象,可以在范围内共享数据
- request域:代表一次请求的范围,一般用于一次请求中转发的多个资源中共享数据

JavaWeb-Request讲解_第10张图片

 API
	1. 设置数据
			void setAttribute(String name, Object o)
			
	2. 获取数据
			Object getAttribute(String name)
			
	3. 删除数据
			void removeAttribute(String name)
			
			
 生命周期
	1. 何时创建
			用户发送请求时,创建request
	2. 何时销毁
			服务器返回响应是,销毁request
	
	3. 作用范围
			一次请求,包含多次转发

coding:

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("aServlet处理功能上....");
        // 转发到BServlet
       /* // 1.获得转发器对象   path = @WebServlet("/bServlet")
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/bServlet");
        // 2.实现转发功能
        requestDispatcher.forward(request, response);*/

       // 存一个数据
        request.setAttribute("hanbao", "鸡腿堡");


        // 链式编程横
        request.getRequestDispatcher("bServlet").forward(request, response);
    }

}



@WebServlet("/bServlet")
public class BServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("bServlet处理功能下....");
        // 获取数据
        String hanbao = (String) request.getAttribute("hanbao");
        System.out.println("hanbao:" + hanbao);
    }

}

3.获取ServletContext对象

应用上下文对象,表示一个web项目

JavaWeb-Request讲解_第11张图片

通过reuqest,可以获得ServletContext对象

public ServletContext  getServletContext();

四,案例

案例分析:

JavaWeb-Request讲解_第12张图片

1.新建项目,并导入工具包,编写index.html




    
    index



用户登录

用户:
密码:

2.User实体类

// 用户对象
public class User {

    private String username;// 用户名

    private String password;// 密码

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

3.LoginServlet类, SuccessServlet类,FailServlet类

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.设置request解码方式
        request.setCharacterEncoding("UTF-8");
        // 2.获取浏览器请求参数,map集合
        Map parameterMap = request.getParameterMap();

        // 3.使用BeanUtils工具类,封装user对象中
        User user = new User();
        try {
            BeanUtils.populate(user, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        // 4.判断
        if("wsl".equals(user.getUsername())&&"123".equals(user.getPassword())){
            // 正确
            request.setAttribute("user", user);
            request.getRequestDispatcher("/successServlet").forward(request,response);
        }else{
            // 错误
            request.getRequestDispatcher("/failServlet").forward(request,response);
        }
    }

}


@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.从request域获取user对象
        User user = (User) request.getAttribute("user");
        // 2.友情提示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(user.getUsername() + ",登录成功");
    }

}



@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.友情提示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("用户名或密码错误..");
    }

}



问题总结:

请求转发与请求重定向的区别
 
JavaWeb-Request讲解_第13张图片
通过上图,我们可以简单总结几点转发和重定向的区别:
1. 转发在一次请求中完成,重定向是两次请求
2. 转发操作发生在服务器内部,重定向是浏览器执行操作
3. 转发地址栏不变(只有一次请求,一个地址),重定向,地址栏变化(两次请求,两个地址)
4. 转发可以在一次请求中共享数据,重定向不行(重定向两次请求,每次都会创建新的 request 对象)。

 

使用技巧:

1.自定义Servlet模板

JavaWeb-Request讲解_第14张图片

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebServlet("/${Class_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
        this.doPost(request,response);
    }

    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {

    }
 
}

2.IDEA 代码抛异常快捷方式

快捷方式一:(光标移到该代码行,Alt+Enter),可以异常外抛出,也可以try-catch:

JavaWeb-Request讲解_第15张图片

快捷方式二:(光标移到该代码行,或者选中该行代码,Ctrl+Alt+T):

JavaWeb-Request讲解_第16张图片

 

 

你可能感兴趣的:(JavaWeb)