HttpServletRequest**对象表明客户端的请求,当客户端经过HTTP协议访问服务器时,**HTTP请求头中的全部信息都封装在这个对象中,开发人员经过这个对象的方法,能够得到客户这些信息。javascript
简单来讲,要获得浏览器信息,就找HttpServletRequest对象css
什么是防盗链呢?好比:我如今有海贼王最新的资源,想要看海贼王的要在个人网页上看。如今别的网站的人看到我有海贼王的资源,想要把个人资源粘贴在他本身的网站上。这样我独家的资源就被一个CTRL+C和CTRL+V抢走了?而反盗链就是不能被他们CRTL+C和CRTL+Vhtml
这样我就划不来啦【个人广告你来没看呢!】。想要看个人资源,就必须通过个人首页点进去看。java
想要实现这样的效果,就要获取Referer这个消息头,判断Referer是否是从个人首页来的。若是不是从个人首页来的,跳转回个人首页。web
//获取到网页是从哪里来的 String referer = request.getHeader("Referer"); //若是不是从个人首页来或者从地址栏直接访问的, if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) { //回到首页去 response.sendRedirect("/zhongfucheng/index.jsp"); return; } //能执行下面的语句,说明是从个人首页点击进来的,那没问题,照常显示 response.setContentType("text/html;charset=UTF-8"); response.getWriter().write("路飞作了XXXXxxxxxxxxxxxxxxxx");
\浏览器
<form action="/zhongfucheng/Servlet111" method="post"> <table> <tr> <td>用户名</td> <td><input type="text" name="username"></td> </tr> <tr> <td>密码</td> <td><input type="password" name="password"></td> </tr> <tr> <td>性别</td> <td> <input type="radio" name="gender" value="男">男 <input type="radio" name="gender" value="女">女 </td> </tr> <tr> <td>爱好</td> <td> <input type="checkbox" name="hobbies" value="游泳">游泳 <input type="checkbox" name="hobbies" value="跑步">跑步 <input type="checkbox" name="hobbies" value="飞翔">飞翔 </td> </tr> <input type="hidden" name="aaa" value="my name is zhongfucheng"> <tr> <td>你的来自于哪里</td> <td> <select name="address"> <option value="广州">广州</option> <option value="深圳">深圳</option> <option value="北京">北京</option> </select> </td> </tr> <tr> <td>详细说明:</td> <td> <textarea cols="30" rows="2" name="textarea"></textarea> </td> </tr> <tr> <td><input type="submit" value="提交"></td> <td><input type="reset" value="重置"></td> </tr> </table>
//设置request字符编码的格式 request.setCharacterEncoding("UTF-8"); //经过html的name属性,获取到值 String username = request.getParameter("username"); String password = request.getParameter("password"); String gender = request.getParameter("gender"); //复选框和下拉框有多个值,获取到多个值 String[] hobbies = request.getParameterValues("hobbies"); String[] address = request.getParameterValues("address"); //获取到文本域的值 String description = request.getParameter("textarea"); //获得隐藏域的值 String hiddenValue = request.getParameter("aaa"); ....各类System.out.println().......
常见的get方式提交数据有:使用超连接,sendRedirect()服务器
格式以下:markdown
sendRedirect("servlet的地址?参数名="+参数值 &"参数名="+参数值);
<a href="/zhongfucheng/Servlet111?username=xxx">使用超连接将数据带给浏览器</a>
//接收以username为参数名带过来的值 String username = request.getParameter("username"); System.out.println(username);
细心的朋友会发现,我在获取表单数据的时候,有这句代码request.setCharacterEncoding("UTF-8");
,若是没有这句代码,会发生什么事呢?咱们看看。网络
来这里咱们来分析一下乱码的缘由,在前面的博客中我已经介绍了,Tomcat服务器默认编码是ISO 8859-1,而浏览器使用的是UTF-8编码。浏览器的中文数据提交给服务器,Tomcat以ISO 8859-1编码对中文编码,当我在Servlet读取数据的时候,拿到的固然是乱码。而我设置request的编码为UTF-8,乱码就解决了。app
接下来使用get方式传递中文数据,把表单的方式改为get便可
当咱们访问的时候,又出现乱码了!
request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name");
结果仍是乱码。这是为何呢?我明明已经把编码设置成UTF-8了,按照post方式,乱码问题已经解决了!。咱们来看看get和post方式的区别在哪?为何post方式设置了request编码就能够解决乱码问题,而get方式不能呢。
首先咱们来看一下post方法是怎么进行参数传递的。当咱们点击提交按钮的时候,数据封装进了Form Data中,http中多了一个上传请求头,既然request对象封装了http请求,因此request对象能够解析到发送过来的数据,因而只要把编码设置成UTF-8就能够解决乱码问题了。
//此时获得的数据已是被ISO 8859-1编码后的字符串了,这个是乱码 String name = request.getParameter("username"); //乱码经过反向查ISO 8859-1获得原始的数据 byte[] bytes = name.getBytes("ISO8859-1"); //经过原始的数据,设置正确的码表,构建字符串 String value = new String(bytes, "UTF-8");
上面的代码有些难理解,我画张图说明一下:
咱们都知道Tomcat默认的编码是ISO 8859-1,若是在Tomcat服务器的配置下改为是UTF-8的编码,那么就解决服务器在解析数据的时候形成乱码问题了
在8080端口的Connector上加入URIEncoding="utf-8"
,设置Tomcat的访问该端口时的编码为utf-8,从而解决乱码,这种改法是固定使用UTF-8编码的
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>
、
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" useBodyEncodingForURI="true" />
request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name");
手写超连接若是附带中文参数问题,要URL重写,在JSP博客中会讲到
总结:
以前讲过使用response的sendRedirect()能够实现重定向,作到的功能是页面跳转,使用request的getRequestDispatcher.forward(request,response)实现转发,作到的功能也是页面跳转,他们有什么区别呢?如今我先来讲下转发
//获取到requestDispatcher对象,跳转到index.jsp RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp"); //调用requestDispatcher对象的forward()实现转发,传入request和response方法 requestDispatcher.forward(request, response);
上面已经说了,能够经过sendRedirect()重定向能够在资源尾部添加参数提交数据给服务器。那么转发能不能提交数据给服务器呢?
答案明显是能够的,而且使用这种方法很是频繁
//以username为关键字存zhongfucheng值 request.setAttribute("username", "zhongfucheng"); //获取到requestDispatcher对象 RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet222"); //调用requestDispatcher对象的forward()实现转发,传入request和response方法 requestDispatcher.forward(request, response);
//获取到存进request对象的值 String userName = (String) request.getAttribute("username"); //在浏览器输出该值 response.getWriter().write("i am :"+userName);
如上图所示,Servlet222成功拿到了request对象在Servlet111存进的数据。
如今问题又来了,咱们能够使用ServletContext和request实现Servlet之间的通信,那么咱们用哪种呢?通常的原则:可使用request就尽量使用request。由于ServletContext表明着整个web应用,使用ServletContext会消耗大量的资源,而request对象会随着请求的结束而结束,资源会被回收。使用request域进行Servlet之间的通信在开发中是很是频繁的。
若是在调用forward方法以前,在Servlet程序中写入的部份内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。 也就是说:不要在转发以前写数据给浏览器
咱们来试试是否是真的会出现异常。
OutputStream outputStream = response.getOutputStream(); outputStream.write("--------------------------------------------".getBytes()); //关闭流,确保让数据到浏览器中 outputStream.close(); //跳转 request.getRequestDispatcher("/Foot").forward(request, response);
不少人都搞不清楚转发和重定向的时候,资源地址究竟怎么写。有的时候要把应用名写上,有的时候不用把应用名写上。很容易把人搞晕。记住一个原则:给服务器用的直接从资源名开始写,给浏览器用的要把应用名写上
根据上面说明了转发和重定向的区别也能够很容易归纳出来。转发是带着转发前的请求的参数的。重定向是新的请求。
典型的应用场景:
RequestDispatcher对象调用forward()能够实现转发上面已经说过了。RequestDispatcher还有另一个方法include(),该方法能够实现包含,有什么用呢?
咱们在写网页的时候,通常网页的头部和尾部是不须要改变的。若是咱们多个地方使用Servlet输出网头和网尾的话,须要把代码从新写一遍。而使用RequestDispatcher的include()方法就能够实现包含网头和网尾的效果了。
request.getRequestDispatcher("/Head").include(request, response); response.getWriter().write("--------------------------------------------"); request.getRequestDispatcher("/Foot").include(request, response);