Web服务端技术:Servlet开发 4

1 请求处理流程

        1.浏览器(客户端)通过 HTTP 协议来访问服务器的资源,Servlet 主要用来处理 HTTP 请求。

        2.Servlet 容器接收HTTP 请求,会针对该请求分别创建一个 HttpServletRequestHttpServletReponse 对象。        

        3.容器将两个对象传入 service() 方法,并调用该方法。

        4.在 service() 方法中,通过 HttpServletRequest 对象获取客户端信息以及请求的相关信息。

        5.对 HTTP 请求进行处理。

        6.请求处理完成后,将响应信息封装到 HttpServletReponse 对象中

        7.Servlet 容器将响应信息返回给客户端

        8.当 Servlet 容器将响应信息返回给客户端后,对象被销毁。

2 HttpServletRequest

该对象用于获取请求数据,例如请求方式、请求的资源以及请求中携带的参数等等。

request对象继承体系结构:           

        ServletRequest        --    接口         

                        |    继承     

        HttpServletRequest    -- 接口         

                        |    实现     

        org.apache.catalina.connector.RequestFacade 类(tomcat)

2.1 请求行方法

获取请求行信息

        GET /web/weather?city=101180101 HTTP/1.1

1. String getMethod();   请求方式

        GET

2. String getContextPath();   获取虚拟目录

        /web

3. String getServletPath();   获取Servlet路径

        /weather

4. String getQueryString();   获取get方式请求参数

        city=101180101

5. getRequestURI() / getRequestURL;获取请求URI

          /web/weather 和 http:localhost:8080/web/weather

6. String getProtocol();   获取协议及版本

        HTTP/1.1

get请求方式

 post请求方式

2.2 请求头方法

获取请求头信息

1. String getHeader(String name);

        通过请求头的名称获取请求头的值

2. Enumeration<String> getHeaderNames(); 

        获取所有的请求头名称

2.3 请求体方法

获取请求体信息

获取流对象

        1. BufferedReader getReader();  获取get方式请求参数

        2. ServletInputStream getInputStream();获取字节输入流,可以操作所有类型数据

1.HTTP协议中没有明确规定GET请求是否能带body,市场上部分浏览器会不支持GET请求带body。

2.HTTP 协议未定义 GET 请求的 body 语义,如果想用 GET 请求发送 body,得先为其定义语义,并确保上下游都能很好的支持。

2.4 请求参数方法

获取请求参数

        GET方式:参数放在URL后面 获取方式:request.getQueryString()

        POST方式:参数放实体内容中 获取方式:request.getInputStream()

获取到的结果形式:

获取请求参数方法

1. Enumeration<String> request.getParameterNames();

        获取所有参数名称列表

2.String request.getParameter("参数名");   

        根据参数名称获取参数值

3.String[] request.getParameterValues("参数名");

        根据参数名获取参数值(可以获取多个值的参数,例如多选框提交的参数)

4. Map<String, String[]> request.getParameterMap()

        得到名称和值的map集合

编码问题

        在Tomcat7及之前的版本中,Tomcat默认GET方法传输的编码格式为ISO-8859-1,因此会产生乱码问题

编码问题解决办法:

        在调用request.getParameter()方法之前设置解码所查询的码表: request.setCharacterEncoding("utf-8");

注意:该方法只能对请求实体内容的数据编码,由于POST提交的数据在实体内容中,所以该方法对POST方法有效,而GET方式提交参数在URI后面,所以该方法对GET方法无效

修改POST方式参数编码:

        request.setCharacterEncoding("utf-8");

修改GET方式参数编码:

        手动解码: String name = new String(name.getBytes("iso-8859-1"),"utf-8");

2.5 请求转发

        请求转发,一种在服务器内部的资源跳转方式。 是在服务端将请求交给另外一个资源来处理并返回给浏览器,在浏览器端并没有察觉到该过程。

请求转发步骤

1. 通过request对象获取请求转发器对象RequestDispatcher            request.getRequestDispatcher(String path)

2. 使用RequestDispatcher对象来进行转发:

        forward(ServletRequest request, ServletResponse response)

请求转发特点

        1. 在请求发送过程中,浏览器只是发送一次请求

        2. 浏览器地址栏路径不发生变化

        2. 只能转发到当前服务器内部资源

        3. 转发是一次请求

过程分析:

        1. 浏览器只发送了一次请求,浏览器的地址栏不会发生改变

        2. 请求过程中只产生一个request和response对象

        3. 多个Servlet共享同一个request和response对象

        4. 通过 request.getRequestDispatcher("x").forward(request,response)方式实现

优点

        1. 无论本次请求涉及到多少servlet,浏览器只是发送一次请求

        2. Servlet之间调用发生在服务器计算机上,节省服务器与浏览器之间往返次数增加处理服务速度。

        3. 可以在转发时利用共享的request对象进行数据传递。

3 HttpServletResponse

3.1 重点对象

        Tomcat接收HTTP请求,则创建一个HttpServletResponse对象,供Servlet程序使用。

        不仅包含了响应的数据,还可通过相关方法来操作这些数据,包括设置响应头、发送错误状态码、写入响应内容等。

传递数据

        通过流来给客户端传递数据的

        该对象用来设置响应数据。

字节流  getOutputStream()    常用于下载(传递二进制数据)

字符流  getWriter()        常用于回传字符串(非常常用)

HttpServletResponse

        该对象用来设置响应数据,通过response对象可以改变响应的信息。

设置响应行

        response.setStatus()  设置状态码

设置响应头

        response.setHeader("name","value")  设置响应头

3.2 重定向

        服务端根据逻辑,发送一个状态码(302),同时响应头中通过location属性,告诉浏览器重新去请求的地址.

        1. 地址栏显示的是新的URL,浏览器地址栏会发生变化

        2. 浏览器至少发送两次请求(只有第一次请求是用户手动发送的,后续请求都是浏览器自动发送的)

示例

例如登录成功后跳转到新的页面时就可以使用它。

        response.setStatus(302);

        response.setHeader("location", "/ObjectDemo/redirect.jsp");

由于功能的特殊性,可以简写为:

        response.sendRedirect("/ObjectDemo/redirect.jsp ");

案例:定时刷新和延时跳转

        /**  

        * 定时刷新 浏览器通过refresh响应头,得到刷新实践后会重新发起请求  

        */

        // response.setHeader("refresh", "1"); // 每隔1秒刷新页面

         /**  

        * 隔n秒之后跳转到另外的页面  

        */

        response.setHeader("refresh", "3;url= /ObjectDemo_war_exploded/redirect.jsp "); // 3秒之后跳转

请求转发与重定向的区别

转发

        a)地址栏不会改变

        b)转发只能转发到当前web应用内的资源

        c)可以在转发过程中,可以把数据保存到request对象

重定向            

        a)地址栏会改变,变成重定向到地址。

        b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。

        c)不能在重定向的过程把数据保存到request中。

设置响应头

        content-type:描述发送给浏览器的数据类型

        response.setHeader("content-type", "text/html"); response.setContentType("text/html"); // 和上面等价,推荐此种写法

3.3 编码设置

实体内容

        response.getWriter().write();   发送字符实体内容

        如果发送了中文会发现有乱码,为什么?

        response.getOutputStream().write()  发送字节实体内容

响应编码格式问题

        在Servlet中输出响应的编码格式:

        System.out.println("响应编码格式:" + response.getCharacterEncoding());

        可以发现输出的是:

解决方法:

        在getWriter之前设置编码格式:

        response.setCharacterEncoding("utf-8");

        可以直接合并到content-type中:

        response.setContentType("text/html; charset=utf-8");

        如果使用response.getOutputStream().write(),则直接传递字节数据,此时将不会进行查询码表,所以会直接传递当前的编码格式数据。 所以response.setCharacterEncoding对字节流无效

项目中的编码问题统一解决方案

      在请求方法的开头直接设置请求和响应的编码,然后再进行其他代码处理:

        protected void doGet(HttpServletRequest request,

        HttpServletResponse response) . . . {    

                request.setCharacterEncoding("utf-8");    

                response.setContentType("text/html; charset=utf-8");

        }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值