100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 22-05-21 西安 javaweb(07) HttpServletRequest和HttpServletResponse 转发与重定

22-05-21 西安 javaweb(07) HttpServletRequest和HttpServletResponse 转发与重定

时间:2023-09-29 00:18:18

相关推荐

22-05-21 西安 javaweb(07) HttpServletRequest和HttpServletResponse 转发与重定

HttpServletRequest和HttpServletResponse

它俩分别是用来获取请求报文,设置响应报文!

HttpServletRequest封装了请求报文,我们可以从中获取到的内容有:

1.获取请求参数

2.获取请求行(展示当前请求的信息)

3.获取请求头信息

4.请求转发

1.HttpServletRequest获取请求参数

String request.getParameter(name):获取浏览器传输的单个的请求参数String[] request.getParameterValues(name):获取浏览器传输的多个同名的请求参数的值的数组

准备一个页面用于提交用户名、密码、爱好

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1>Hello,tomcat</h1><form action="FirstServlet" method="post">用户名:<input type="text" name="username"><br>密码:<input type="password" name="password"><br>爱好:<input type="checkbox" name="hobby" value="AA">AA<input type="checkbox" name="hobby" value="BB">BB<input type="checkbox" name="hobby" value="CC">CC<input type="checkbox" name="hobby" value="CC">DD<input type="checkbox" name="hobby" value="CC">EE<br><input type="submit" value="提交"><br></form></body></html>

页面效果如下:

别问我问什么选CD????单纯喜欢这俩个字母而已,咦~

public class FirstServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, UnsupportedEncodingException {// 不管是get还是post都能获取// 获取浏览器传输的单个请求参数String username = request.getParameter("username");String password = request.getParameter("password");//获取浏览器传输多个同名的请求参数String[] hobbies = request.getParameterValues("hobby");System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobbies));}}

控制台打印结果:

HttpServletRequest解决请求参数中文乱码问题

request.setCharacterEncoding("UTF-8");

因为编码不一致:浏览器有浏览器的编码,服务器有服务器的编码。

tomcat8.5 解决了get请求的中文乱码问题,tomcat 7 get请求有中文乱码问题

获取请求参数之前设置,在设置编码之前不能获取任何获取请求参数才有效

先设置编码过滤器,再来设置获取请求参数过滤器

public class FirstServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, UnsupportedEncodingException {//解决中文乱码request.setCharacterEncoding("UTF-8");//获取请求参数String username = request.getParameter("username");String password = request.getParameter("password");String[] hobbies = request.getParameterValues("hobby");System.out.println("username:"+username+",password:"+password+",hobby:"+ Arrays.toString(hobbies));}}

中文乱码问题得到解决:

2.request获取请求行中请求相关信息

request.getContextPath();//获取当前web应用上下文路径

public class ServletMM extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 获取当前web应用上下文路径String contextPath = request.getContextPath();// 获取协议String scheme = request.getScheme();// 获取服务器的端口号int serverPort = request.getServerPort();// 获取服务器ip地址String serverName = request.getServerName();// 获取发送请求的统一资源定位符(在网络中的地址)StringBuffer requestURL = request.getRequestURL();// 获取发送请求的统一资源标识符 (资源在服务器的地址,上下文路径下的资源路径)String requestURI = request.getRequestURI();System.out.println("统一资源定位符:"+requestURL.toString());System.out.println("统一资源标识符:"+requestURI);}}

3.request获取请求头(键值对)信息

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//获取当前请求的来源路径String cookie = request.getHeader("cookie");//参数写请求头的键,键不区分大小写System.out.println("cookie:"+cookie);}

request获取请求体(扩展)

request.getReader()//获取字符输出流,缓冲流可以一次读一行

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {BufferedReader bufferedReader = request.getReader();//获取字符输出流,缓冲流可以一次读一行String line = bufferedReader.readLine();System.out.println(line);}

4.request请求转发

是将当前的请求传递到下一个资源继续进行处理,是响应浏览器的一种方式。

request.getRequestDispatcher("/success.html").forward(request,response);//请求转发

请求转发特点:

请求转发时浏览器地址栏没有发生变化,浏览器只发送了一次请求,最终实现的页面跳转发生在服务器内部,浏览器是不知道的!

这里/success.html,“/”可以加也可以不加,加了之后是绝对路径,因为是请求转发,所以/是由服务器解析的,这个路径问题一会专门讲。用老师的话说:路径问题是个大问题!

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 请求转发:是将当前的请求传递到下一个资源继续进行处理// 交给页面处理请求就是展示给用户request.getRequestDispatcher("/success.html").forward(request,response);}

请求转发举例

理论上我请求的是ServletMM,实际上给我转发到了success.html(也即在服务器内部给我跳转到了success.html,页面显示的最终效果就是success.html的内容)。

且我们发现请求转发时浏览器地址栏没有发生变化。也就是说,既然显示的是success.html页面的内容,地址栏应该像第二张图那样才对呀,可是事实上请求转发的地址栏就是第一张图那样。应证了那句:请求转发是在服务器内部跳转的。

HttpServletResponse

封装服务器发送到浏览器的响应报文,因此可以通过此对象设置当前响应相关的信息

PrintWriter中的write()和print()会把数据存储在响应体响应给浏览器

区别是:print可以将任意类型输出给浏览器,它俩效果是一样的。

1.将任意类型输出给浏览器

//字符输出流,输出文本 标签会被浏览器解析response.getWriter().print("<h1>Tomorrow is another day</h1>");//字节输出流,输出文件ServletOutputStream outputStream = response.getOutputStream();// writer.write("helloworld");

如向浏览器发送内容 <h1>Tomorrow is another day</h1>,看的出来h1标签也是被解析了的

那要是向浏览器发送的内容中有中文呢?

如我要给浏览器发送 <h1>顺为凡,逆则仙</h1>,如下:

//字符输出流,输出文本 标签会被浏览器解析response.getWriter().print("<h1>顺为凡,逆则仙</h1>");

这时候浏览器就蒙蔽了,,,解析成这个样子了:

解决响应到浏览器数据的乱码问题:

//设置响应报文中存储数据的编码格式response.setCharacterEncoding("UTF-8");//设置浏览器解码格式,以文本形式存在的html,// 这一块忘记点进去setContentType去源码找text/html;charset=UTF-8response.setContentType("text/html;charset=UTF-8");//字符输出流,输出文本 标签会被浏览器解析response.getWriter().print("<h1>顺为凡,逆则仙</h1>");

效果很清晰:输出了我喜欢的玄幻小说之一《仙逆》的主旨

设置浏览器解码格式时也可以这么写,但是没必要,不推荐

response.setHeader("Content-Type", "text/html;charset=UTF-8");

2.重定向

重定向也可以跳转页面,它是浏览器发送2次请求,浏览器地址栏会发生变化。最终实现的页面跳转发生在浏览器端。

//由服务器通知浏览器再次发送请求跳转到重定向的路径response.sendRedirect("success.html");

响应浏览器的3种方式:

1.响应浏览器数据

2.请求转发

3.重定向

总结:业务逻辑处理成功使用重定向,业务逻辑处理失败使用请求转发

以下来自我自己的总结,在新的页面中有操作且有数据要带过去展示的话用请求转发,有操作但是没有数据带过去的情况下,用重定向。没有操作没有数据带过去的单纯跳转页面用转发。

补充:

有操作有数据也可以使用重定向, 这时你只要将数据存入到session中也是可以的.

没有操作没有数据带过去用 重定向和内部转发 都可以.用转发是因为转发可以访问WEB-INF目录下的资源

请求转发和重定向区别:

区别一:

转发时地址栏不变,即显示的是servlet地址,浏览器只发送一次请求,最终页面跳转发生在服务器端;重定向时地址栏改变,即显示最终重定向的地址,浏览器只发送2次请求,最终页面跳转发生在浏览器端

区别二:

WEB-INF下的页面具有隐藏性、安全性,浏览器不能直接访问,只有服务器才能访问,即只有请求转发才能访问到,重定向不能访问到。以后大部分情况,把页面放在WEB-INF下。不会把css,js放在WEB-INF下

区别三:

请求转发可以访问请求域中的数据,重定向不可以。

那是因为转发是浏览器发送的一次请求,request对象是同一个。重定向发送2次请求,2次请求对应2个request对象

登录失败,需要把错误信息共享在请求域中,这是因为另外俩种域对象太大了,所以业务逻辑处理失败使用转发。

相对路径和绝对路径

相对路径指目标资源相对于当前位置的路径

绝对路径

static web中,绝对路径指目标资源在磁盘上的路径web application中,绝对路径指目标资源在服务器上的路径

相对路径的缺点对应绝对路径的优点 :

1、相对路径跟目标资源的位置和当前的位置有关,其中任何一个位置发生变化,则相对路径失效

2、相对路径跟目标资源的位置和当前的位置有关,在不同的位置访问同一个资源,没有统一的访问路径

3、相对路径在请求转发中不靠谱,因为相对地址会发生变化

对第3条的理解:在请求转发到的页面中,由于请求转发是浏览器发送的一次请求,因此地址栏中的地址不变,即访问的是servlet的地址,因此当前位置发生了变化,从而影响到页面中的相对路径

web application的绝对路径

很简单:就是”/“开头的路径。但是这个“/”分为服务器解析和浏览器解析

服务器解析的绝对路径中,/表示"http://localhost:8080/上下文路径"下开始访问

浏览器解析的绝对路径中,/表示"http://localhost:8080"下开始访问

服务器解析的绝对路径的2种情况:①web.xml中使用的绝对路径,②请求转发到的绝对路径

如url-pattern标签中的"/" <url-pattern>/ServletMM</url-pattern>

浏览器解析的绝对路径的情况:①html页面中标签设置的绝对路径,② 重定向到的绝对路径

html页面中标签绝对路径3种处理方式

由于是浏览器所解析的绝对路径,所以缺失了上下文路径,有3种处理方式

方式1、手动添加上下文路径

方式2、base标签

方式3、将web应用的上下文路径设置为"/"

第二种方式:

<base href="/day05_web/">

href里有俩个"/",后面那个"/"为什么写在base里,因为base标签不能作用于绝对路径的(以"/"开头的路径)

第三种方式:

"/" 由浏览器和服务器解析的绝对路径就是一样的了,实际项目就是这么用的

重定向到的绝对路径的处理方式:

在重定向到绝对路径前拼接request.getContextPath();

System.out.println("上下文路径: "+request.getContextPath());//重定向由浏览器解析,要加上下文路径response.sendRedirect(request.getContextPath() + "/test.html");

浏览器重定向后展示的页面

控制台输出上下文路径为:

22-05-21 西安 javaweb(07) HttpServletRequest和HttpServletResponse 转发与重定向 web应用的路径问题 解决中文乱码问题

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。