zoukankan      html  css  js  c++  java
  • Servlet---JavaWeb技术的核心基础,JavaWeb框架的基石(二)


    一、Servlet之Request
            Web服务器会对收到的每一次客户端http请求分别创建一个用于代表请求的request对象和代表响应的response对象。要获取客户端提交的数据需通过request,要想容器输出数据需通过response。
            1、HttpServletRequest
               HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法可以会的客户的相关信息。
            2、Request常用方法(参考官方API)
                获得客户机信息:
                     getRequestURL,返回客户端发出请求时的完整URL
                     getRequestURI, 返回请求行中的资源名部分
                     getQueryString, 返回请求行中的查询字符串,通常为?后边携带的参数信息
                     getRemoteAddr, 返回客户端IP地址
                     getRemoteHost, 返回客户端的主机名
                     getRemotePort, 返回客户端的网络端口号
                     getLocalAddr, 返回Web服务器的IP地址
                     getLocalName, 返回Web服务器的主机名
                     getMethod, 返回客户端的请求方式(get/post)
                 获得客户机请求头:
                     getHeader() 
                     getHeaders()
                     getHeaderNames()
                 获得客户机请求参数:
                     getParameter()
                     getParameterValues()
                     getParameterNames
            3、Request请求参数的中文乱码问题
                  一般浏览器使用什么编码,则传送的数据就以什么编码,但有许多Web浏览器不发送带有“content-type”头信息的字符编码限定符,而由读取http请求的代码类决定自读的编码方式。
                  默认情况下,如果客户端请求未定义编码限定符,容器(如Tomcat)会用“ISO-8859-1”去创建request reader 和解析post数据。
                  注意:自从Tomcat5.x开始,GET和POST方法提交的信息,Tomcat采用了不同的方式来处理编码,对于POST请求,Tomcat会仍然使用request.setCharacterEncoding方法所设置的编码来处理,如果未设置,则使用默认的"ISO-8859-1"编码。而对GET请求,并不会考虑使用request.setCharacterEncoding方法设置编码,而会永远使用“ISO-8859-1”编码。        
                  所以,一般的解决方式为:
                        POST方式:在最开始设置request.setCharacterEncoding("UTF-8")
                        GET方式: new String(username.getBytes("ISO-8859-1"),"UTF-8")
                        修改Tomcat的配置可以解决URL中中文编码问题:<Connector URIEncoding="UTF-8"/>
              4、转发和包含
                     一个Servlet对象无法获得另一个Servlet对象的引用,如果需要多个Servlet组件共同协作(数据传递),只能使用Servlet规范提供的请求转发和包含这两种方式:
                      请求转发:Servlet(源组件)先对客户请求最初一些预处理操作,然后把请求转发给其他web组件(目标组件)来完成包括生成响应结果在内的后续操作。
                      包含: Servlet(源组件)把其他web组件(目标组件)生成的响应结果包含到自身的响应结果中。
                      两者共同点:
                             源组件和目标组件处理的都是同一个酷虎请求,源组件和目标组件共享同一个ServletRequest和ServletResponse对象。
                             目标组件可以为Servlet、JSP、HTML文档等
                             都依赖javax.servlet.RequestDispatcher接口。
               5、RequestDispatcher请求分发器
                         它包含两个方法:
                           forward():把请求转发给目标组件
                           include():包含目标组件的响应结果
                         得到RequestDispatcher对象
                             1、ServletContext对象的getRequestDispatcher(String path1)。path1必须用绝对路径,即以‘/’开头,若用相对路径会抛出IllegalArgumentException异常
                             2、ServletRequest对象的getRequestDispatcher(String path2)。 path2可以用绝对路径也可以用相对路径。
                         如果使用forward()方法,只会返回目标组件的响应结果,所以不应该在源组件中提交响应结果,而且,如果在源组件调用了Response的flush或close方法,会抛出IllegalStateException异常
                         如果使用include()方法,则源组件与目标组件的输出都会被添加到响应结果中,在目标组件对响应头做的修改会被忽略
               6、请求范围
                         web应用范围内的共享数据作为ServletContext对象的属性而存在,只要共享ServletContext对象也就共享了其属性。
                         请求范围内的共享数据作为ServletRequest对象的属性而存在,只要共享了ServletRequest对象,也就共享了其数据。
     
    二、Servlet之Response
              1、HttpServletResponse
                 HttpServletResponse对象代表服务器的响应,这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
              2、Response常用方法
                 setStatus();设置状态码
                 setHeader();设置响应头
                 getWriter();返回一个响应的打印流
                 getOutputStream();返回一个响应的字节输出流
                 注意:getWriter与getOutputStream两个方法相互排斥,调用了其中一个方法后就不能再调用另一个,否侧会抛出异常,Servlet引擎会检查输出流是否关闭,并调用close方法,所以不需要自己关闭。
              3、Response中的中文问题
                 通过设置响应头告知客户端编码方式:response.setHeader("Content-Type","text/html;charset=UTF-8")
                 通过meta标签模拟请求头::out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes())
                 通过直接方法:response.setContentType("text/html;charset=UTF-8");这条语句的作用是将自己的编码设置为UTF-8,并告诉浏览器使用UTF-8解码
              4、Response常见应用
                  控制浏览器定时刷新:response.setHeader("Refresh","2");也可以定时刷新到某一个URL
                  控制浏览器缓存当前文档:
    response.addDateHeader("Expires",System.currentTimeMillis()+1000*60*60);//缓存一小时,对于一些不怎么变化的数据,利用缓存能减轻服务器的负担
                  请求重定向:response.sendRedirect(location);
                  重定向特点:
                     Servlet源组件生成的响应结果不会被发送到客户端,response.sendRedirect(location)方法一律返回状态码为302的响应结果。
                     如果源组件在进行重定向之前,已经提交了响应结果,会抛出IllegalStateException异常,所以,不应该在元组件中提交响应结果。
                     Servlet源组件重定向语句后面的代码也会执行。
                     源组件和目标组件不共享一个ServletRequest对象。
                     对于response.sendRedirect(location)方法的参数,如果以"/"开头,表示相当于当前服务器根路径的URL。以"http://"开头,表示一个完整路径。
                     目标组件不必是同一个服务器上的同一个web应用的组件,它可以是任意一个有效的网页。
     
    三、Cookie&Session
            1、什么是会话:     
                用户开一个浏览器,点击对个超链接,访问服务器多个Web资源,然后关闭浏览器,整个过程称之为一个会话。
                每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
            2、保存会话数据的两种技术:
                  Cookie:Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的Web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
                  HttpSession:Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器 创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源是,其他web资源在从用户各自的session中取出数据为用户服务。
            3、Cookie API
                javax.servlet.http.Cookie类用于创建一个Cookie,response接口中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。同样,request接口中也定义了一个个头Cookie方法,它用于获取客户端提交的Cookie。Cookie类的方法:
              public Cookie(String name,String value);
              setValue与getValue方法
              setMaxAge与getMaxAge方法
              setPath与getPath方法
              setDomain与getDomain方法
              getName方法
              由于Cookie保存在客户端,所有,给不给传Cookie是由浏览器决定的,取决于MYURL.startWith(domain+path)完全匹配。domain是主机名加端口号,path是从第一个"/"开始的文件路径。
              cookie.setPath("/");可以让该cookie在同一个服务器下的多个项目共享。
            4、Cookie细节
                一个Cookie只能表示一种信息,它至少患有一个标识该信息的名称(name)和设置值(value)。
                一个Web应用可以给一个浏览器发送多个Cookie;一个浏览器也可以存储多个Web网站的Cookie。
                每个浏览器有自己默认的存放Cookie个数,并限制每个站点存放Cookie的个数,每个Cookie的大小限制为4kb。
                如果创建了一个cookie,并将它发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除,若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
                注意,删除cookie是,path必须一致,否则不会删除。   
            5、Session       
                在web开发中,服务器可以为每个用户浏览器创建一个会话对象(Session对象),把用户数据写到用户浏览器独占的Session中,当前用户使一个浏览器独占一个Session对象。因此,需要保存用户数据时,服务器程序可以用Session保存,统一浏览器可以从用户的Session中取出该用户的数据,为用户服务。
                Session对象有服务器创建,开发人员可以调用request对象的getSession方法得到Session对象。
                浏览器第一次请求时,服务器会在响应头中加入Set-Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8; Path=/Day28ServletResponse/; HttpOnly。当浏览器下次请求时会携带这个Session的唯一标识,Cookie: JSESSIONID=022841F4A201530430481C66F0D29FB8。服务器就之后是同一个用户的行为了。
                服务器内存中的每个Session都有一个32位的id作为唯一标识,Tomcat为每个Session默认的生存时间为30分中。
             6、浏览器禁用Cookie之后的Session处理
                 浏览器禁用Cookie之后,就无法再请求中携带JSESSIONID内容,所以导致服务器共享出问题。Java提供URL重写方案:
                 response.encodeRedirectURL(url);对sendRedirect方法的URL地址进行重写。
                 response.encodeURL(url);对表单action和超链接的url地址进行重写。
                 如果用户浏览器没有禁用Cookie,重写方法什么也不做;如果用户浏览器禁用了Cookie,则重写方法在每个URL地址中携带JSESSIONID,服务器保证了一个用户的每一个请求行为携带SessionID,从而保证Session的作用。
                 Session的invalidate()方法使Session立刻失效。
                 可以在项目的web.xml中配置Session失效时间。
     
     
    四、Servlet高级特性--过滤器
            1、过滤器概述:
             过滤器是Servlet2.3规范新增的功能,也是Servlet容器管理的对象,其结构同Servlet很类似,比如init()方法,destory()方法, 但是功能不同,过滤器主要是在源数据与目的数据之间起过滤作用的中间组件。
            2、过滤器链
             在一个Web应用中,可以一次编写多个过滤器,这些过滤器组合起来,称为一个过滤器链,其执行顺序为注册顺序,先注册的会先执行
            3、编码转换过滤器
              在JavaWeb开发中,初学者经常会遇到java乱码的问题,统一字符编码,是解决乱码问题非常有效的手段,在Web开发中,可以使用过滤器对请求中的参数信息进行编码转换。
            4、权限校验过滤器(清楚整个处理流程)
               根据不同的权限,用户分别能够访问不同的页面。
     
     





  • 相关阅读:
    cnblog项目--20190309
    django js引入失效问题
    Python老男孩 day16 函数(六) 匿名函数
    Python老男孩 day16 函数(五) 函数的作用域
    Python老男孩 day15 函数(四) 递归
    Python老男孩 day15 函数(三) 前向引用之'函数即变量'
    Python老男孩 day15 函数(二) 局部变量与全局变量
    Python老男孩 day14 函数(一)
    Python老男孩 day14 字符串格式化
    Python老男孩 day14 集合
  • 原文地址:https://www.cnblogs.com/rocomp/p/4814765.html
Copyright © 2011-2022 走看看