JavaWeb——(9)Request&Response
2021/5/10 12:29:01
本文主要是介绍JavaWeb——(9)Request&Response,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
一、HttpServletResponse
1.1响应行
1.2响应头
1.3响应正文
1.4常见应用
1.4.1响应编码字符输出流
1.4.2响应编码字节输出流
1.4.3文件下载
1.4.4验证码
1.4.5验证码——工具类实现
1.4.6设置客户端不使用缓存
1.4.7网页定时刷新
1.5请求重定向
1.6 HttpServletResponse对象细节
二、HttpServletRequest
2.1请求行
2.2请求消息头
2.3请求正文
2.3.1获取表单数据
2.3.2操作非表单数据
2.3.3请求转发和请求包含
2.3.4请求编码
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。
首先我们要了解一下Http协议,然后学习HttpServletResponse和HttpServletRequest对象。
关于Http协议可以看之前整理的博客:https://blog.csdn.net/weixin_39478524/article/details/115336677,
Http中很重要的就是请求和响应操作,对应的就是HttpServletRequest对象和HttpServletResponse对象,所有数据的操作都是基于这两个对象封装的。
一、HttpServletResponse
HttpServletResponse对应的是响应消息,负责操作响应的数据,
响应消息可以分为三部分:响应行、响应头和响应正文,我们也分三部分介绍HttpServletResponse如何操作这三部分。
1.1响应行
HTTP/1.1 200 OK
响应消息行主要包括两个部分:协议版本和响应状态码,操作响应行的函数主要就是设置响应状态码,
setStatus(int sc)//设置响应状态码
1.2响应头
响应消息头由一系列的键值对组成,主要有以下方法对响应头进行操作,
sendRedirect(String location)//请求重定向 addHeader(String name, String value)//添加响应头信息 setHeader(String name, String value)//设置响应头信息,没有键时自动添加
我们可以利用setHeader()方法告诉浏览器用什么码表,
response.setHeader("content-type", "text/html;charset=UTF-8");
1.3响应正文
getWrite();//返回字符输出流 getOutputStream();//返回字节输出流 setCharacterEncoding(String charset);//设置字符编码类型 setContentType(String type);//设置文本类型
1.4常见应用
下面我们依次介绍一下response的常见应用
1.4.1响应编码字符输出流
我们测试一下,在响应正文中输出我们想要的字符串,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "ServletDemo1") public class ServletDemo1 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 { response.setCharacterEncoding("Unicode");//设置服务器编码方式,否则默认编码中文会乱码 response.setHeader("content-type","text/html;charset=Unicode");//设置响应消息头编码方式 PrintWriter out=response.getWriter();//得到一个字符输出流 out.write("中文测试");//向客户端响应文本内容 } }
或者也可以直接设置文本编码方式,将设置服务器编码和消息头编码合并为一句,
response.setContentType("text/html;charset=Unicode");//设置文本编码格式
然后配置一下映射的路径,
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servletDemo</servlet-name> <servlet-class>ServletDemo1</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping> </web-app>
显示效果如下:
1.4.2响应编码字节输出流
接着测试一下字节输出流输出信息,
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletDemo2") public class ServletDemo2 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 { ServletOutputStream servletOutputStream=response.getOutputStream();//获取字节输出流 servletOutputStream.write("字节输出流测试".getBytes());//向响应正文输出信息 } }
修改配置信息,
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servletDemo2</servlet-name> <servlet-class>ServletDemo2</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo2</servlet-name> <url-pattern>/demo2</url-pattern> </servlet-mapping> </web-app>
输出结果:
1.4.3文件下载
我们以图片为例,将资源放在工程的src文件夹下,
我们首先将文件输出到客户端,在网页中显示,
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; @WebServlet(name = "ServletDemo3") public class ServletDemo3 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 { String path=this.getServletContext().getRealPath("/WEB-INF/classes/snow.JPG");//得到文件的路径 FileInputStream fileInputStream=new FileInputStream(path);//通过路径得到输入流 ServletOutputStream servletOutputStream=response.getOutputStream();//获取输出到客户端的字节输出流 int len=1; byte b[]=new byte[1024]; while((len= fileInputStream.read(b))!=-1){ servletOutputStream.write(b,0,len);//输出到客户端 } servletOutputStream.close(); fileInputStream.close(); } }
配置一下web.xml文件,
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servletDemo3</servlet-name> <servlet-class>ServletDemo3</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo3</servlet-name> <url-pattern>/demo3</url-pattern> </servlet-mapping> </web-app>
显示效果:
接下来我们更改一下代码,让用户可以直接下载图片,
import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileInputStream; import java.io.IOException; @WebServlet(name = "ServletDemo3") public class ServletDemo3 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 { String path=this.getServletContext().getRealPath("/WEB-INF/classes/snow.JPG");//得到文件的路径 FileInputStream fileInputStream=new FileInputStream(path);//通过路径得到输入流 ServletOutputStream servletOutputStream=response.getOutputStream();//获取输出到客户端的字节输出流 String filename=path.substring(path.lastIndexOf("\\")+1);//获取需要下载的文件名 response.setHeader("content-disposition","attachment;filename="+filename);//告知客户端要下载文件 response.setHeader("content-type","image/jpeg");//告知客户端下载文件的类型 int len=1; byte b[]=new byte[1024]; while((len= fileInputStream.read(b))!=-1){ servletOutputStream.write(b,0,len);//输出到客户端 } servletOutputStream.close(); fileInputStream.close(); } }
网页效果,网页将图片已经下载好了:
1.4.4验证码
验证码是一种防止暴力破解的工具,在某种程度上可以区分人和机器,现在我们制作一个带验证码的登录界面,
首先我们用代码创建验证码,
import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; @WebServlet(name = "ServletDemo4") public class ServletDemo4 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 { int width=100;//图片宽度 int height=25;//图片高度 BufferedImage img=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//在内存中创建一个图像 Graphics g=img.getGraphics();//创建一个画笔 //设置背景 g.setColor(Color.PINK);//设置背景填充颜色 g.fillRect(1,1,width-2,height-2);//设置填充的范围 g.setColor(Color.RED);//设置边框颜色 g.drawRect(0,0,width-1,height-1);//以边框色画出边框 //添加验证码数字 g.setColor(Color.BLUE);//设置文本颜色 g.setFont(new Font("宋体",Font.BOLD|Font.ITALIC,15));//设置字体样式 Random rand=new Random(); String code=rand.nextInt(10)+" "+rand.nextInt(10)+" "+rand.nextInt(10)+" "+rand.nextInt(10);//产生随机验证码 g.drawString(code,20,18); //添加验证码干扰线 for (int i = 0; i < 5; i++) { g.drawLine(rand.nextInt(width),rand.nextInt(height),rand.nextInt(width),rand.nextInt(height));//产生随机坐标的直线 } ImageIO.write(img,"jpg",response.getOutputStream());//将图片对象以流的方式输出到客户端 } }
配置xml文件检验效果,
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servletDemo4</servlet-name> <servlet-class>ServletDemo4</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo4</servlet-name> <url-pattern>/demo4</url-pattern> </servlet-mapping> </web-app>
输入http://localhost:8080/demo4,看看验证码的效果图,
然后我们在html文件中访问该地址,需要注意要加上http协议,否则访问不成功,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>login</title> <script type="text/javascript"> function changeCode(){ var img=document.getElementsByTagName("img")[0];//得到图片元素 img.src="http://localhost:8080/demo4?time="+ new Date().getTime();//重新赋值src路径,加入时间避免浏览器使用缓存的数据不刷新 } </script> </head> <body> <form action="#" method="post"> 用户名:<input type="text" name="userName"/><br> 密码:<input type="password" name="passWord"/><br> 验证码:<input type="text" name="code"/> <img src="http://localhost:8080/demo4" onclick="changeCode()"/><a href="javascript:changeCode()">看不清换一张</a><br> <input type="submit" value="登录"/><br> </form> </body> </html>
访问界面:
刷新之后的效果:
1.4.5验证码——工具类实现
首先我们导入外部的工具类,以IDEA为例:
依次点击File->Project Structure->Libraries,点击加号添加我们的jar工具包ValidateCode.jar,然后新建Servlet导入该工具类,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import cn.dsna.util.images.ValidateCode; @WebServlet(name = "ServletDemo5") public class ServletDemo5 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 { int width=100;//图片宽度 int height=25;//图片高度 int codeCount=4;//验证码字符数量 int lineCount=5;//干扰线数量 ValidateCode validateCode=new ValidateCode(width,height,codeCount,lineCount);//生成验证码 validateCode.write(response.getOutputStream());//输出到网页 } }
然后配置一下映射地址,
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>servletDemo5</servlet-name> <servlet-class>ServletDemo5</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletDemo5</servlet-name> <url-pattern>/demo5</url-pattern> </servlet-mapping> </web-app>
可以看到工具类实现的验证码如下,
1.4.6设置客户端不使用缓存
当页面进行刷新时,正常的验证码都会进行更新,但是如果我们不在验证码地址后加时间,那么浏览器就会认为该资源已经加载过了,
刷新的时候不访问服务器,直接从网页的缓存中提取资源,验证码也就不会刷新,这时我们也可以不在资源后加时间后缀,设置客户端不使用缓存,每次访问资源都要走服务器的通道,那么验证码自然刷新就会更新,
response.setHeader("pragma","no-cache"); response.setHeader("cache-control","no-cache"); response.setHeader("expires","0");
这样验证码每次就会从服务器获取,而不会从缓存中获取了。
1.4.7网页定时刷新
定时刷新用到的还是setHeader方法,设置响应消息头,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Random; @WebServlet(name = "ServletDemo6") public class ServletDemo6 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 { response.setHeader("refresh","1");//设置响应消息头,1s刷新一次 Random random=new Random(); response.getWriter().write(random.nextInt(100)+""); } }
刷新结果:
还可以刷新的时候跳转到指定的url路径,
response.setContentType("text/html;charset=UTF-8");//设置客户端字符集 response.getWriter().write("3s后跳转到百度"); response.setHeader("refresh","3;url=http://www.baidu.com");
1.5请求重定向
请求重定向和请求转发类似,都是客户端请求Servlet1完成某个功能,但是Servlet1无法完成,转而让Servlet2完成,
二者不同的是:
- 转发在服务器端完成的;重定向是在客户端完成的
- 转发的速度快;重定向速度慢
- 转发的是同一次请求;重定向是两次不同请求
- 转发不会执行转发后的代码;重定向会执行重定向之后的代码
- 转发地址栏没有变化;重定向地址栏有变化
- 转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成
请求转发和请求重定向示意图如下,
请求重定向是通过setStatus方法来告诉客户端要重定向到新的url,
通过设置响应消息头来告诉客户端具体重定向的url地址,
response.setStatus(302);//告诉客户端要重定向操作 response.setHeader("location","url");//告诉客户端重定向的url地址
或者也可以将这两个方法使用一个方法替代,
response.sendRedirect("url");//告知客户端要重定向,并且重定向到url地址
我们测试一下请求重定向,新建两个Servlet:ServletDemo7、ServletDemo8,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletDemo7") public class ServletDemo7 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 { System.out.println("请求重定向"); response.setStatus(302);//告知客户端需要重定向 response.setHeader("location","http://localhost:8080/demo8");//告诉客户端重定向的地址 } }
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletDemo8") public class ServletDemo8 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 { System.out.println("收到!"); } }
我们启动tomcat服务器,请求demo7,http://localhost:8080/demo7,
结果会将请求重定向到demo8,http://localhost:8080/demo8,
1.6 HttpServletResponse对象细节
- getOutputStream和getWriter
- getOutputStream方法用于得到输出二进制数据的ServletOuputStream对象
- getWriter方法用于得到输出文本数据的Printwriter对象
- 这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。会抛异常
- Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端
- Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象
二、HttpServletRequest
HttpServletRequest对象代表了客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,
开发人员通过这个对象的方法,可以获得用户的信息,如下:
getRequestURL();//方法返回客户端发出请求时的完整URL getRequestURI();//方法返回请求行中的资源名部分 getQueryString();//方法返回请求行中的参数部分 getRemoteAddr();//方法返回发出请求的客户机的IP地址 getRemoteHost();//方法返回发出请求的客户机的完整主机名 getRemotePort();//方法返回客户机所使用的网络端口号 getLocalAddr();//方法返回WEB服务器的IP地址 getLocalName();//方法返回WEB服务器的主机名 getMethod();//得到客户机请求方式
2.1请求行
比如请求行消息:Get http://localhost:8080/demo8?username=zs http/1.1
getMethod();//获得请求方式 getRequestURL();//返回客户端发出请求时的完整URL getRequestURI();//返回请求行中的资源名部分 getContextPath();//当前应用的虚拟目录 /demo8 getQueryString();//返回请求行中的参数部分
我们测试一下这几个方法,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletRequestDemo1") public class ServletRequestDemo1 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 { System.out.println(request.getMethod());//输出请求方式 System.out.println(request.getRequestURL());//输出客户端发出请求时的完整URL System.out.println(request.getRequestURI());//输出请求行中资源名部分 System.out.println(request.getContextPath());//输出当前应用的虚拟目录 System.out.println(request.getQueryString());//输出请求行中的参数部分 } }
登录http://localhost:8080/Demo1?username=peru网站,输出结果如下:
2.2请求消息头
String getHeader(String name);/根据头名称得到头信息值 Enumeration getHeaderNames();//得到所有头信息name Enumeration getHeaders(String name);//根据头名称得到相同名称头信息值
我们输出一下请求消息头的所有信息,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; @WebServlet(name = "ServletRequestDemo2") public class ServletRequestDemo2 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 { Enumeration names=request.getHeaderNames();//获取所有请求消息头的name while(names.hasMoreElements()){ String nextElement=(String)names.nextElement(); System.out.println(nextElement+":"+request.getHeader(nextElement));//逐个输出请求消息头的键值对 } System.out.println(request.getHeader("User-Agent"));//获得请求消息头信息 } }
输出结果如下,
2.3请求正文
2.3.1获取表单数据
getParameter(name);//根据表单中name属性的名,获取value属性的值方法 getParameterValues(String name);//专业为复选框取取提供的方法 getParameterNames();//得到表单提交的所有name的方法 getParameterMap();//得到表单提交的所有值的方法。做框架用,非常实用 getInputStream();//以字节流的方式得到所有表单数据
我们首先制作一个注册界面,设置表单数据让用户填写,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://localhost:8080/Demo3" method="post"> 用户名:<input type="text" name="userName"/><br/> 密码:<input type="password" name="passWord"/><br/> 性别:<input type="radio" name="sex" value="男" checked="checked"/>男 <input type="radio" name="sex" value="女"/>女<br/> 爱好:<input type="checkbox" name="hobby" value="运动"/>运动 <input type="checkbox" name="hobby" value="听歌"/>听歌 <input type="checkbox" name="hobby" value="看书"/>看书 <input type="checkbox" name="hobby" value="睡觉"/>睡觉<br/> 居住地:<select name="city"> <option>————请选择————</option> <option value="北京">北京</option> <option value="上海">上海</option> <option value="广州">广州</option> <option value="深圳">深圳</option> <option value="武汉">武汉</option> </select><br/> <input type="submit" value="注册"/> </form> </body> </html>
然后我们在servlet应用中获取表单数据,并输出(注意这里要将form标签的action属性设置为servlet应用的映射访问地址),获取表单数据一共有四种方法,
1、第一种为直接通过表单项的名字获取表单项的值然后输出,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletRequestDemo3") public class ServletRequestDemo3 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 { request.setCharacterEncoding("UTF-8");//设置服务器编码方式(要与浏览器编码方式相同),避免获取网页信息时中文显示乱码 //获取提交的表单数据 System.out.println("用户名:"+request.getParameter("userName"));//输出用户名 System.out.println("密码:"+request.getParameter("passWord"));//输出密码 System.out.println("性别:"+request.getParameter("sex"));//输出性别 String[] hobbys=request.getParameterValues("hobby");//获取爱好字符串数组 System.out.print("爱好:"); for (int i = 0; hobbys!=null && i < hobbys.length; i++) { System.out.print(hobbys[i]); } System.out.println(); System.out.println("居住地:"+request.getParameter("city"));//输出居住地 } }
然后我们进入到注册界面,填写好表单数据,点击注册可以看到输出结果:
2、我们还可以先获取所有的表单项名字,通过名字获取表单项的值,
request.setCharacterEncoding("UTF-8");//设置服务器编码方式(要与浏览器编码方式相同),避免获取网页信息时中文显示乱码 Enumeration names=request.getParameterNames();//获取所有表单项的名字 while(names.hasMoreElements()){ String name=(String) names.nextElement();//获取表单的名字 System.out.print(name+":"); String[] values=request.getParameterValues(name);//得到该表单项的值 for (int i = 0; values!=null && i < values.length; i++) { System.out.print(values[i]+" "); } System.out.println(); }
结果如图,
3、第三种方法为使用getParameterMap(),该方法可以获取表单提交的所有值,一般在框架中经常使用,
首先我们生成用户类,里面存放着对应的用户注册的信息,也就是表单的信息(同时还要实现toString、set和get方法),
//在实体类中的字段要与表单中的name名一致 public class User { private String userName; private String passWord; private String sex; private String[] hobby; private String city; }
然后我们将得到的表单数据封装到用户类中,
User user=new User(); Map<String,String[]> map=request.getParameterMap();//获取提交的表单数据集合 for (Map.Entry<String,String[]> m:map.entrySet()) { String name=m.getKey(); String[] value=m.getValue(); //创建一个属性描述器 try { PropertyDescriptor propertyDescriptor=new PropertyDescriptor(name,User.class);//将集合中的值内省到User类的变量上 Method setter=propertyDescriptor.getWriteMethod();//得到User类中的set方法 if (value.length==1){ setter.invoke(user,value[0]);//给一个值的变量赋值 }else{ setter.invoke(user,(Object)value);//给多个值的变量赋值,比如数组 } } catch (Exception e) { e.printStackTrace(); } } System.out.println(user);//输出用户信息
结果如下图,
基于这个方法,我们可以直接使用框架来提取表单数据,我们导入两个jar包:commons-beanutils-1.8.3.jar和commons-logging-1.1.1.jar,这种方法代码就很简洁了,jar包地址为:
链接:https://pan.baidu.com/s/1NcpIN_uFD1sIKZKLYIVX4g
提取码:1qyv
复制这段内容后打开百度网盘手机App,操作更方便哦
request.setCharacterEncoding("UTF-8");//设置服务器编码方式(要与浏览器编码方式相同),避免获取网页信息时中文显示乱码 try { User user=new User(); BeanUtils.populate(user,request.getParameterMap()); System.out.println(user); } catch (Exception e) { e.printStackTrace(); }
结果如下,
4、最后一种方式是以字节流的形式获取表单数据,使用的方法为getInputStream(),
ServletInputStream servletInputStream=request.getInputStream();//获取字节输入流 int len=0; byte[] bytes=new byte[1024]; while((len=servletInputStream.read(bytes))!=-1){ String name=new String(bytes,0,len); System.out.println(new String(name.getBytes("iso-8859-1"),"UTF-8")); } servletInputStream.close();
2.3.2操作非表单数据
非表单数据就是非表单提交的数据,这些数据在request域对象中存储,一般我们使用以下的方法进行操作,
void setAttribute(String name, Object value); Object getAttribute(String name); Void removeAttribute(String name);
这里我们用转发来测试一下非表单数据如何进行传输的,我们在Demo4中将非表单数据放在request中,
import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletRequestDemo4") public class ServletRequestDemo4 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 { request.setCharacterEncoding("UTF-8");//设置服务器编码方式(要与浏览器编码方式相同),避免获取网页信息时中文显示乱码 response.setContentType("text/html;charset=UTF-8"); String str="java";//非表单数据 request.setAttribute("data",str);//将非表单数据添加到request域中 RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Demo5");//获取服务器资源包装器 requestDispatcher.forward(request,response);//请求转发 } }
然后在Demo5中获取数据,
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletRequestDemo5") public class ServletRequestDemo5 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 { response.setContentType("text/html;charset=UTF-8"); String att=(String)request.getAttribute("data"); System.out.println(att); } }
输出结果如下,
2.3.3请求转发和请求包含
转发和1.5的重定向类似,都是客户端发送请求给Servlet1,Servlet1无法完成让Servlet2完成,
转发是Servlet1来将请求转发给Servlet2,客户端只用发送一次请求;而重定向则是Servlet1告诉客户端Servlet2可以做,让客户端自己重新发送请求,客户端一共发送了两次请求。
RequestDispatcher getRequestDispatcher(String path);//得到请求转发或请求包含的协助对象 forward(ServletRequest request, ServletResponse response);//转发的方法 include(ServletRequest request, ServletResponse response);//请求包含
我们新建一个Servlet,将请求转发给Demo1,
import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet(name = "ServletRequestDemo4") public class ServletRequestDemo4 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 { request.setCharacterEncoding("UTF-8");//设置服务器编码方式(要与浏览器编码方式相同),避免获取网页信息时中文显示乱码 response.setContentType("text/html;charset=UTF-8"); RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Demo1");//获取服务器资源包装器 requestDispatcher.forward(request,response);//请求转发 } }
然后配置一下web.xml配置文件,开启服务器访问http://localhost:8080/Demo4,请求转发结果如下,
请求包含就是Servlet(源组件)把其他Servlet(目标组件)生成的响应结果包含到自身的响应结果中,
request.getRequestDispatcher(“接收请求的Servlet 路径”). include(request,response)
2.3.4请求编码
表单的提交方式一般分为post和get,为了解决乱码问题有不同的方法,
request.setCharacterEncoding("UTF-8");//告诉服务器客户端什么编码,只能处理post请求方式 String name = new String(name.getBytes(“iso-8859-1”),”UTF-8”);//对每个字符串进行重新编码,用于处理get请求方式
这篇关于JavaWeb——(9)Request&Response的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南