Servlet 学习(三)
HTTP 请求的构成
1、HTTP 请求行:
- 请求方式,比如 GET 、POST 等
- 本次请求的URI ,比如 /hello
- 协议和版本号
2、 HTTP 请求报头: (头部/首部/请求头)
- 请求头和请求正文之间用空行分隔
- 常见的请求报头
3、 HTTP 请求正文:
- 一种是 请求参数 ,比如 /hello?username=zhangsanfeng&password=wudang2017
- 一种是 针对上传文件 等操作
HttpServletRequest 类型的对象
1、Servlet 容器响应Web 客户端请求的时序图
2、与HTTP请求行对应的方法
- 请求方式: String getMethod()
- URI : String getRequestURI()
- 协议: String getProtocol()
3、与HTTP请求报头对应的方法
- String getHeader( String name ) 获取指定名称的请求报头的取值
- Enumeration<String> getHeaders( String name ) 获取指定名称的请求报头的取值(取值有多个,比如cookie)
- long getDateHeader( String name ) 获取指定名称的请求报头的取值 ( 返回以毫秒为单位的时间 )
- int getIntHeader( String name ) 获取指定名称的请求报头的取值 ( 以 int 形式返回 )
- Enumeration<String> getHeaderNames() 获取所有的请求报头的名称
4、与HTTP请求正文对应的方法
获取请求参数:
- String getParameter( String name ) 获取指定的请求参数对应的值
- String[] getParameterValues( String name ) 获取指定的请求参数对应的值 ( 取值有多个,比如 checkbox )
- Map< String , String[] > getParameterMap() 获取所有的请求参数及取值( 取值是个数组 )
- Enumeration<String> getParameterNames() 获取所有的请求参数的名称
获取WEB客户端上传的数据:
- ServletInputStream getInputStream() 在 Servlet 3.0 之前获取上传数据的方法 ( 以字节形流式返回 )
- BufferedReader getReader() 在 Servlet 3.0 之前获取上传数据的方法 ( 以字符流形式返回 )
- Part getPart( String name ) 根据 名称 获得 一个 multipart/form-data POST request 中指定名称对应的 Part 对象
<input type="file" name="upfile" > =========> request.getPart( "upfile" )
- Collection<Part> getParts() 获取 multipart/form-data POST request 中对应的所有的 Part 对象
测试案例:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <servlet> <servlet-name>ParseRequestServlet</servlet-name> <servlet-class>ecut.request.ParseRequestServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ParseRequestServlet</servlet-name> <url-pattern>/parse</url-pattern> </servlet-mapping> <servlet> <servlet-name>FirstUploadServlet</servlet-name> <servlet-class>ecut.request.FirstUploadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FirstUploadServlet</servlet-name> <url-pattern>/upload/first</url-pattern> </servlet-mapping> <servlet> <servlet-name>SecondUploadServlet</servlet-name> <servlet-class>ecut.request.SecondUploadServlet</servlet-class> <!-- 启用 Servlet 3.x 所支持的文件上传方式 --> <multipart-config> <location>D:/files</location> </multipart-config> <!-- location 指定的是文件上传后的存储位置 --> </servlet> <servlet-mapping> <servlet-name>SecondUploadServlet</servlet-name> <url-pattern>/upload/second</url-pattern> </servlet-mapping> <servlet> <servlet-name>ThirdUploadServlet</servlet-name> <servlet-class>ecut.request.ThirdUploadServlet</servlet-class> <!-- 启用 Servlet 3.x 所支持的文件上传方式 --> <multipart-config> <location>D:/files</location> </multipart-config> <!-- location 指定的是文件上传后的存储位置 --> </servlet> <servlet-mapping> <servlet-name>ThirdUploadServlet</servlet-name> <url-pattern>/upload/third</url-pattern> </servlet-mapping> </web-app>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Request</title> </head> <body> <a href="/Servlet/parse?username=Amy&password=123456" >访问 ParseRequestServlet</a> <h5>GET</h5> <form action="/Servlet/parse" method="get" > <input type="text" name="username" placeholder="用户名"> <br> 性别: <input type="radio" name="gender" value="女"> 我是靓女 <input type="radio" name="gender" value="男"> 我是靓仔 <br> 爱好: <input type="checkbox" name="hobby" value="eat">吃饭 <input type="checkbox" name="hobby" value="sleep">睡觉 <input type="checkbox" name="hobby" value="wc">上厕所 <br> <input type="submit" value="提交"> </form> <h5>POST</h5> <form action="/Servlet/parse" method="post" > <input type="text" name="username" placeholder="用户名"> <br> 性别: <input type="radio" name="gender" value="女"> 我是靓女 <input type="radio" name="gender" value="男"> 我是靓仔 <br> 爱好: <input type="checkbox" name="hobby" value="eat">吃饭 <input type="checkbox" name="hobby" value="sleep">睡觉 <input type="checkbox" name="hobby" value="wc">上厕所 <br> <input type="submit" value="提交"> </form> <h5>文件上传(古代)</h5> <!-- method 必须是 POST ,enctype 必须是 multipart/form-data enctype默认是对数据进行 application/x-www-form-urlencoded编码--> <form action="/Servlet/upload/first" method="post" enctype="multipart/form-data"> <input type="file" name="upfile" > <input type="submit" value="上传" > </form> <h5>文件上传( 从 Servlet 3.0 开始 )</h5> <!-- method 必须是 POST ,enctype 必须是 multipart/form-data --> <form action="/Servlet/upload/second" method="post" enctype="multipart/form-data"> <input type="file" name="upfile" > <input type="submit" value="上传" > </form> <h5>文件上传( 从 Servlet 3.0 开始 )</h5> <!-- method 必须是 POST ,enctype 必须是 multipart/form-data --> <form action="/Servlet/upload/third" method="post" enctype="multipart/form-data"> <input type="file" name="upfile1" > <br> <input type="file" name="upfile2" > <br> <input type="file" name="upfile3" > <br> <input type="file" name="upfile4" > <br> <input type="submit" value="上传" > </form> </body> </html>
package ecut.request; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Enumeration; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ParseRequestServlet extends HttpServlet { private static final long serialVersionUID = 5473447295646845596L; @Override protected void service( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { request.setCharacterEncoding( "UTF-8" ); response.setCharacterEncoding( "UTF-8" ); response.setContentType( "text/html;charset=UTF-8" ); PrintWriter p =response.getWriter(); // 获取 HTTP HTTP 请求行中的相关信息 String method = request.getMethod(); String uri = request.getRequestURI() ; String protocol = request.getProtocol() ; System.out.println( "HTTP 请求行:"); System.out.println("\t请求方式 = " + method); System.out.println("\tURI = " + uri); System.out.println("\t协议/版本号= " + protocol); p.println("<p>HTTP 请求行:</p>"); p.println("<p style='text-indent:2em;'>请求方式 = " + method+"</p>"); p.println("<p style='text-indent:2em;'>URI = " + uri+"</p>"); p.println("<p style='text-indent:2em;'>协议/版本号 = " + protocol+"</p>"); // 获取HTTP 请求报头 Enumeration<String> headerNames = request.getHeaderNames(); System.out.println( "HTTP 请求报头:" ); p.println( "<p>HTTP 请求报头:"+"</p>" ); while( headerNames.hasMoreElements() ) { String name = headerNames.nextElement(); // 获取单个的HTTP 请求报头的名称 String value = request.getHeader( name ) ; // 获得指定名称对应的HTTP 请求报头的值 System.out.println( "\t" + name + " = " + value ); p.println("<p style='text-indent:2em;'>" + name + " = " + value +"</p>"); } // 获取HTTP 请求参数 Map<String,String[]> paramMap = request.getParameterMap(); Set< Entry<String, String[]> > entrySet = paramMap.entrySet(); System.out.println( "HTTP 请求参数:" ); p.println( "<p>HTTP 请求参数:" ); for( Entry<String, String[]> e : entrySet ){ String name = e.getKey() ; String[] value = e.getValue() ; System.out.println( "\t" + name + " : " + Arrays.toString( value ) ); p.println( "<p style='text-indent:2em;'>" + name + " : " + Arrays.toString( value ) +"</p>"); } } }
运行结果如下:
控制台输出文件的内容。
获取指定的请求参数对应的值取值有多个的测试案例:
运行结果如下:
HTTP 请求行:
请求方式 = GET
URI = /Servlet/parse
协议/版本号= HTTP/1.1
HTTP 请求报头:
host = localhost:8080
user-agent = Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
accept = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-language = zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
accept-encoding = gzip, deflate
referer = http://localhost:8080/Servlet/pages/request/index.html
connection = keep-alive
upgrade-insecure-requests = 1
HTTP 请求参数:
username : [AmyZheng]
gender : [男]
hobby : [eat, sleep]
文件上传测试案例一:
package ecut.request; import java.io.BufferedReader; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FirstUploadServlet extends HttpServlet { private static final long serialVersionUID = -7777691027208490971L; @Override protected void doGet( HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { throw new RuntimeException( "不支持GET方式上传" ); } @Override protected void doPost( HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { request.setCharacterEncoding( "UTF-8" ); // 上传文件时,只考虑文本文件,不考虑其它文件 BufferedReader reader = request.getReader(); //InputStream in = request.getInputStream(); String s ; while( ( s = reader.readLine() ) != null ){ System.out.println( s ); } } }
运行结果如下:
页面跳转到http://localhost:8080/Servlet/upload/first
控制台输出文件内容
-----------------------------296501829912081
Content-Disposition: form-data; name="upfile"; filename="Http.txt"
Content-Type: text/plain
文件内容省略
-----------------------------296501829912081--
文件上传测试案例二:
package ecut.request; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; public class SecondUploadServlet extends HttpServlet { private static final long serialVersionUID = 4485463572490572537L; @Override protected void doGet( HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { throw new RuntimeException( "不支持GET方式上传" ); } @Override protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { // String username = request.getParameter( "username" ) ; // <input type="text" name="username" > Part part = request.getPart( "upfile" ) ; // <input type="file" name="upfile" > System.out.println( part ); /* Servlet 3.0 中获得文件名的做法 String cd = part.getHeader( "Content-Disposition" ); System.out.println( cd ); String s = "filename=\""; int index = cd.indexOf( s );//找到filename的位置 String name = cd.substring( index + s.length() , cd.length() - 1 );//获取文件名 System.out.println( name ); */ // part.getName() ; // name="upfile" String filename = part.getSubmittedFileName(); // Servlet 3.1 开始出现的方法 part.write( filename ); } }
运行结果如下:
页面跳转到http://localhost:8080/Servlet/upload/second
D:\files目录下增加了一个文件
文件上传测试案例三:
package ecut.request; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; public class ThirdUploadServlet extends HttpServlet { private static final long serialVersionUID = 4485463572490572537L; @Override protected void doGet( HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { throw new RuntimeException( "不支持GET方式上传" ); } @Override protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { upfile("upfile1",request); upfile("upfile2",request); upfile("upfile3",request); upfile("upfile4",request); } void upfile(String upfile,HttpServletRequest request) throws ServletException, IOException{ Part part = request.getPart( upfile) ; String filename = part.getSubmittedFileName(); part.write( filename ); } }
运行结果如下:
页面跳转到http://localhost:8080/Servlet/upload/third
D:\files目录下增加了四个文件
转载请于明显处标明出处