Request请求

Request请求:
  • Request请求,就是客户端希望从服务器端获取资源,向服务器发出询问。在B/S架构中,就是客户浏览器向服务器发出询问。在我们的JavaEE工程中,客户浏览器发出询问,要遵循HTTP协议所规定的。
  • 请求对象,就是在JavaEE工程中,用于发送请求的对象。我们常用的对象就是ServletRequest和HttpServletRequest,它们的区别就是是否和HTTP协议有关。是Servlet四大域之一
请求对象方法:
返回值方法名说明
StringgetContextPath()获取虚拟目录名称
StringgetServletPath()获取Servlet映射路径
StringgetRemoteAdd()获取访问者ip地址
StringgetQueryString()获取请求的消息数据
StringgetRequestURI()获取统一资源标识符
StringBuffergetRequestURL()获取统一资源定位符

演示:

@WebServlet("/requestMethod")
public class RequestMethod extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 访问地址http://localhost:8081/demo/requestMethod
        // getContextPath()	获取虚拟目录名称   /demo
        System.out.println(req.getContextPath());
        // getServletPath()	获取Servlet映射路径   /requestMethod
        System.out.println(req.getServletPath());
        // getRemoteAdd()	获取访问者ip地址   0:0:0:0:0:0:0:1
        System.out.println(req.getRemoteAddr());
        // getQueryString()	获取请求的消息数据    null
        System.out.println(req.getQueryString());
        // getRequestURI()	获取统一资源标识符    /demo/requestMethod
        System.out.println(req.getRequestURI());
        // getRequestURL()	获取统一资源定位符   http://localhost:8081/demo/requestMethod
        System.out.println(req.getRequestURL());
        // URI的范围更大(共和国),URL更具体(中华人民共和国)
    }
}
获取请求头方法:
返回值方法名说明
StringgetHeader(String name)根据请求头名称获取一个值
EnumerationgetHeaders(String name)根据请求头名称获取多个值
EnumerationgetHeaderNames()获取所有请求头

演示:

@WebServlet("/requestHeaderDemo")
public class RequestHeaderDemo extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // getHeader(String name)	根据请求头名称获取一个值
        System.out.println(req.getHeader("connection"));
        System.out.println("------------------------");

        // getHeaders(String name)	根据请求头名称获取多个值
        Enumeration<String> values = req.getHeaders("accept-encoding");
        while (values.hasMoreElements()) {
            String value = values.nextElement();
            System.out.println(value);
        }
        System.out.println("------------------------");

        // getHeaderNames()	获取所有请求头
        Enumeration<String> names = req.getHeaderNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = req.getHeader(name);
            System.out.println(name + " : " + value);
        }
    }
获取请求参数信息:
返回值方法名说明
StringgetParameter(String name)根据名称获取数据
String[]getPaeameterValues(String name)根据名称获取所有数据
EnumerationgetParameterNames()获取所有名称
Map<String,String[]>getParameterMap()获取所有参数的键值对

演示:
注册页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面</title>
</head>
<body>

<form action="/servletDemo08" method="get" autocomplete="off">
    姓名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    爱好:<input type="checkbox" name="hobby" value="game">游戏
    <input type="checkbox" name="hobby" value="study">学习<br/>
    <button type="submit">提交</button>
</form>

</body>
</html>

获取请求参数:

@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // String	getParameter(String name)	根据名称获取数据
        System.out.println(req.getParameter("username"));
        System.out.println(req.getParameter("password"));
        System.out.println("——————————————————————");

        // String[]	getParameterValues(String name)	根据名称获取所有数据
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("——————————————————————");

        // Enumeration<String>	getParameterNames()	获取所有名称
        Enumeration<String> names = req.getParameterNames();
        while (names.hasMoreElements()) {
            System.out.println(names.nextElement());
        }
        System.out.println("——————————————————————");

        // Map<String,String[]>	getParameterMap()	获取所有参数的键值对
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {
            String[] values = map.get(key);
            System.out.print(key + ":");
            for (String value : values) {
                System.out.print(value + " ");
            }
            System.out.println();
        }
    }
}
获取参数手动封装到对象:

学生类:

public class Student {
    private String username;
    private String password;
    private String[] hobby;
}

注册页面不变,改一下提交路径即可

@WebServlet("/servletDemo09")
public class ServletDemo09 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.获取所有的数据
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobby = req.getParameterValues("hobby");

        // 2.封装学生对象
        Student student = new Student(username, password, hobby);

        // 3.打印学生对象
        System.out.println(student);
    }
}
反射封装对象:
@WebServlet("/servletDemo10")
public class ServletDemo10 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {

        // 1. 获取所有的数据
        Map<String, String[]> map = req.getParameterMap();

        // 2. 封装学生对象
        Student student = new Student();

        // 3. 遍历集合
        for (String name : map.keySet()) {
            String[] value = map.get(name);
            try {
                // 获取Student对象的属性描述器,就是获取get/set,然后把get/set封装到pd里
                // 拿到User对象中的属性描述器。是谁的属性描述器:是由构造函数的第一个参数决定的。第二个参数是指定javabean的字节码
                PropertyDescriptor pd = new PropertyDescriptor(name, student.getClass());//参数指的就是拿哪个类的哪个属性的描述器
                // 设置javabean属性的值
                Method writeMethod = pd.getWriteMethod();

                if (value.length > 1) {
                    writeMethod.invoke(student, (Object) value);
                } else {
                    writeMethod.invoke(student, value);//第一个参数是指的给哪个对象,第二个参数指的是赋什么值
                }
            } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }

        // 4. 输出对象
        System.out.println(student);
    }
}
BeanUtils封装对象:

使用apache的commons-beanutils实现封装
如果遇到报500可能是没有将jar包要导入到项目中

@WebServlet("/servletDemo11")
public class ServletDemo11 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        //1.获取所有的数据
        Map<String, String[]> map = req.getParameterMap();

        //2.封装学生对象
        Student stu = new Student();
        try {
            // 通过该方法将map中的数据映射/封装到javabean的get和set方法中
            BeanUtils.populate(stu, map);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //4.输出对象
        System.out.println(stu);
    }
}
流对象获取请求信息:

方法:

返回值方法名说明
BufferedReadergetReader()获取字符输入流
ServletInputStreamgetInputStream()获取字节输入流

演示:

@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 字符流获取必须使用post,字符流不是new出来的不需要关闭
/*        BufferedReader reader = req.getReader();
        String len;
        while ((len = reader.readLine()) != null) {
            System.out.println(len);
        }*/
        // 如果用post出现乱码就在代码前加个编码格式就可以了
        // setCharacterEncoding:设置编码格式
        req.setCharacterEncoding("UTF-8");
        // 字节流
        ServletInputStream inputStream = req.getInputStream();
        byte[] bytes = new byte[1024];
        int len;
        while ((len = inputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, len));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
中文乱码问题:

GET方式请求:

  • GET方式请求的正文是在地址栏中,在Tomcat8.5版本及以后,Tomcat服务器已经帮我们解决了,所以不会有乱码问题了。

POST方式请求

  • 在POST方式请求中,我们的乱码问题可以用如下代码解决:
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
  
        /*
         * GET方式:正文在地址栏
         * username=%D5%C5%C8%FD
         * %D5%C5%C8%FD是已经被编过一次码了
         *
         * 解决办法:
         * 	 使用正确的码表对已经编过码的数据进行解码。
         */
        // setCharacterEncoding:设置编码格式
        req.setCharacterEncoding("UTF-8");
        String username = request.getParameter("username");
        System.out.println(username);
}
请求域:
  • 请求域(request域):可以在一次请求范围内进行共享数据
  • 一般用于请求转发 的多个资源中共享数据
请求对象操作共享数据方法:
返回值方法名说明
voidsetAttribute(String name,Object value)向请求域对象中存储数据
objectsetAttribute(String name)通过名称获取请求域对象中的数据
voidremoveAttribute(String name)通过名称移除请求域对象中的数据
请求转发:

客户端的一次请求到达以后,发现借助其他的Servlet来实现功能

特点:

  • 浏览器地址不变
  • 域对象中的数据不丢失
  • 负责转发的Servlet转发前后的显示正文会丢失
  • 由转发的目的地来响应客户端
请求转发的方法:
返回值方法名说明
RequestDispatchergetRequestDispatcher(String name)获取请求调度对象
voidforward(ServletRequest req,ServletResponse resp)实现转发
@WebServlet("/servletDemo12")
public class ServletDemo12 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置共享数据
        req.setAttribute("itzhuzhu", "正在学习");
        // 获取请求调度对象
        RequestDispatcher rd = req.getRequestDispatcher("servletDemo13");
        // 实现转发功能
        rd.forward(req, resp);
    }
}
@WebServlet("/servletDemo13")
public class ServletDemo13 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取共享数据
        System.out.println(req.getAttribute("itzhuzhu"));
        System.out.println("ServletDemo13执行");
    }
}
请求包含:

可以合并其它Servlet中的功能一起响应给客户端

特点:

  • 浏览器地址不变
  • 域对象数据不丢失
  • 被包含的Servlet响应头会丢失
请求包含方法:
返回值方法名说明
RequestDispatchergetRequestDispatcher(String name)获取请求调度对象
voidinclude(ServletRequest req,ServletResponse resp)实现包含
@WebServlet("/servletDemo14")
public class ServletDemo14 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置共享数据
        req.setAttribute("itzhuzhu", "正在学习");
        // 获取请求调度对象
        RequestDispatcher rd = req.getRequestDispatcher("/servletDemo13");
        // 实现包含功能
        rd.include(req, resp);
    }
}
重定向和请求转发 :
  • 重定向:通过各种方法将各种网络请求重新定个方向转到其它位置,地址会变
  • 请求转发:客户端发起请求后,在服务器之间的跳转,然后服务器返回页面给客户端进行显示,地址不变
package com.zhy.http.okhttp; import android.os.Handler; import android.os.Looper; import android.text.TextUtils; import android.util.Log; import com.zhy.http.okhttp.cookie.SimpleCookieJar; import okhttp3.Call; import okhttp3.OkHttpClient; import okhttp3.Response; import com.zhy.http.okhttp.builder.GetBuilder; import com.zhy.http.okhttp.builder.PostFileBuilder; import com.zhy.http.okhttp.builder.PostFormBuilder; import com.zhy.http.okhttp.builder.PostStringBuilder; import com.zhy.http.okhttp.callback.Callback; import com.zhy.http.okhttp.https.HttpsUtils; import com.zhy.http.okhttp.request.RequestCall; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; /** * Created by zhy on 15/8/17. */ public class OkHttpUtils { public static final String TAG = "OkHttpUtils"; public static final long DEFAULT_MILLISECONDS = 10000; private static OkHttpUtils mInstance; private OkHttpClient mOkHttpClient; private Handler mDelivery; private OkHttpUtils() { OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder(); //cookie enabled okHttpClientBuilder.cookieJar(new SimpleCookieJar()); mDelivery = new Handler(Looper.getMainLooper()); if (true) { okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); } mOkHttpClient = okHttpClientBuilder.build(); } private boolean debug; private String tag; public OkHttpUtils debug(String tag) { debug = true; this.tag = tag; return this; } public static OkHttpUtils getInstance() { if (mInstance == null) { synchronized (OkHttpUtils.class) { if (mInstance == null) { mInstance = new OkHttpUtils(); } } } return mInstance; } public Handler getDelivery() { return mDelivery; } public OkHttpClient getOkHttpClient() { return mOkHttpClient; } public static GetBuilder get() { return new GetBuilder(); } public static PostStringBuilder postString() { return new PostStringBuilder(); } public static PostFileBuilder postFile() { return new PostFileBuilder(); } public static PostFormBuilder post() { return new PostFormBuilder(); } public void execute(final RequestCall requestCall, Callback callback) { if (debug) { if(TextUtils.isEmpty(tag)) { tag = TAG; } Log.d(tag, "{method:" + requestCall.getRequest().method() + ", detail:" + requestCall.getOkHttpRequest().toString() + "}"); } if (callback == null) callback = Callback.CALLBACK_DEFAULT; final Callback finalCallback = callback; requestCall.getCall().enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, final IOException e) { sendFailResultCallback(call, e, finalCallback); } @Override public void onResponse(final Call call, final Response response) { if (response.code() >= 400 && response.code() <= 599) { try { sendFailResultCallback(call, new RuntimeException(response.body().string()), finalCallback); } catch (IOException e) { e.printStackTrace(); } return; } try { Object o = finalCallback.parseNetworkResponse(response); sendSuccessResultCallback(o, finalCallback); } catch (Exception e) { sendFailResultCallback(call, e, finalCallback); } } }); } public void sendFailResultCallback(final Call call, final Exception e, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onError(call, e); callback.onAfter(); } }); } public void sendSuccessResultCallback(final Object object, final Callback callback) { if (callback == null) return; mDelivery.post(new Runnable() { @Override public void run() { callback.onResponse(object); callback.onAfter(); } }); } public void cancelTag(Object tag) { for (Call call : mOkHttpClient.dispatcher().queuedCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } for (Call call : mOkHttpClient.dispatcher().runningCalls()) { if (tag.equals(call.request().tag())) { call.cancel(); } } } public void setCertificates(InputStream... certificates) { mOkHttpClient = getOkHttpClient().newBuilder() .sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)) .build(); } public void setConnectTimeout(int timeout, TimeUnit units) { mOkHttpClient = getOkHttpClient().newBuilder() .connectTimeout(timeout, units) .build(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

itzhuzhu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值