文章目录
- 前置知识点
- URL和URI
- HTTP请求报文和HTTP响应报文
- Request
- 请求行
- 请求头
- 请求体
- 特殊信息
- 获取客户机和服务器主机信息
- 请求参数
- 直接封装
- 引用类型
- POST请求请求参数乱码
- 文件上传
- 案例(与前面的`getServletContext`结合)
- Request做请求的转发
前置知识点
URL和URI
- URL:统一资源位置
- URI:统一资源标识符
- 端口号后面的所有部分都是URI
- 举例:
比如请求:http://localhost:8080/demo/hello.jsp
URL:http://localhost:8080/demo/hello.jsp
URI:/demo/hello.jsp
HTTP请求报文和HTTP响应报文
- HTTP请求报文
- 请求行
- 请求方法(GET/POST)
- 请求URL
- 请求协议
- 请求头
- 格式是
key:value
- 比较特殊的请求头:
- Content-Type:由浏览器提供给服务器的正文类型
- Accept:浏览器期望从服务器获得正文的类型( 服务器提供给浏览器的正文类型)
- Host:主机ip
- 格式是
- (空行)
- 请求体
- 普通的Get请求和form表单提供的Get/Post请求,如果携带了参数它的格式是
key1=value1&key2=value2&key3=value3
等
- 普通的Get请求和form表单提供的Get/Post请求,如果携带了参数它的格式是
- 携带Json数据的post请求
{}
或[]
- 请求行
- HTTP响应报文
- 响应行
- 协议
- 响应状态码
- 响应头
- 格式是
key:value
- Content-Type:服务器提供给浏览器的正文类型,后面通常会跟charset,比如
application/json;charset=utf-8
- 格式是
- (空行)
- 响应体
- 如果是json,Content-Type中通常是application/json
- 响应行
Request
请求行
eg:
POST http://101.43.69.31:8083/admin/auth/login HTTP/1.1
GET http://localhost:8080/demo3/hello?username=zhangsan HTTP/1.1
信息 | 内容 | 方法 | 返回值 | 说明 |
---|---|---|---|---|
请求方法 | POST、GET | getMethod() | String | 获得请求方法 |
URL | http://101.43.69.31:8083/admin/auth/login | getRequestURL() | StringBuffer | 获得请求URL |
URI | /admin/auth/login、/demo3/hello | getRequestURI() | String | 获得请求URI |
context-path | /demo3 | getContextPath() | String | 获得上下文 |
服务器ip | 101.43.69.31、localhost | getLocalAddr() | String | 获得ip |
端口号 | 8083、8080 | getLocalPort() | int | 获得端口号 |
QueryString | username=zhangsan | getQueryString() | String | 获得Get请求的查询字符串 |
协议 | HTTP/1.1 | getProtocol() | String | 获得通讯协议 |
eg:
/**
* 构造一个GET请求:http://localhost:8080/demo1/user?username=zs HTTP/1.1
*
* 构造一个POST请求:http://localhost:8080/demo1/user HTTP/1.1
*/
@WebServlet(value = "/user")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
core(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
core(req,resp);
}
private void core(HttpServletRequest requset, HttpServletResponse response) {
// 获得请求方法
String method = requset.getMethod();
// 获得URL
// http://localhost:8080/demo1/user
StringBuffer requestURL = requset.getRequestURL();
String url = requestURL.toString();
// 获取本地ip
// 0:0:0:0:0:0:0:1
String localAddr = requset.getLocalAddr();
// 获取本地端口号
// 8080
int localPort = requset.getLocalPort();
// 获取上下文的路径
// /demo1
String contextPath = requset.getContextPath();
// 获取URI
// /demo1/user
String requestURI = requset.getRequestURI();
// 获得Get请求的查询字符串
// username=zs
String queryString = requset.getQueryString();
// 获取协议的部分
// HTTP/1.1
String protocol = requset.getProtocol();
}
}
请求头
- 请求头中的信息,都是
key:value
的形式- 可以知道有哪一些请求头 Key → 获得所有的请求头
- 也可以知道这些请求头当中的值是什么 Value → 获得特定Key对应的Value
- 请求头大小写不敏感
方法 | 返回值 | 说明 |
---|---|---|
getHeaderNames() | Enumeration<String> | 获得所有的请求头,可以通过遍历的方式来使用,使用方式类似于Iterator |
getHeader(String) | String | 传入的是请求头的Key,返回的是请求头的value |
eg:
@WebServlet("/header")
public class HeaderServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// 获得了请求头的枚举的类型
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
// 获取所有的请求头
String headerName = headerNames.nextElement();
// 获取请求头对应的value
String headerValue = request.getHeader(headerName);
// System.out.println(headerName + ":" + headerValue);
// 如果只想打印accept的值
// toLowerCase()是改成纯小写
if ("accept".equals(headerName.toLowerCase())) {
String accept = request.getHeader("accept");
System.out.println("accept = " + accept);
}
}
}
}
请求体
- 构造一个
form
表单
<body>
<form action="/demo1/body1" method="post">
<input name="username" type="text"><br>
<input type="submit">
</form>
</body>
- Postman构造的
- 通过fiddler抓取Postman构造的POST请求报文:
POST http://localhost:8080/demo1/body1 HTTP/1.1
User-Agent: PostmanRuntime/7.37.0
Accept: */*
Postman-Token: 58bc8447-cae4-438e-ab71-b53d58dd80f6
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 11
// 这部分是请求体
username=zs
- 字节流InputStream、字符流Reader
- 字符流通常不写出,之后请求参数会以JSON字符串的形式提供(getReader()读取即可)
- 在同一个方法中,不能同时使用字符流和字节流
- 原因:里面有标记,使用其中的一个流会导致标记后移,另外一个流无法使用
内容 | 方法 | 返回值 | 描述 |
---|---|---|---|
字节流 | getInputStream() | ServletInputStream | 获得字节流 |
字符流 | getReader() | BufferedReader | 获得字符流 |
eg:
- 字符流举例
/**
* 字符流
*/
@WebServlet("/body1")
public class BodyServlet1 extends HttpServlet {
// 构造POST请求
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// 首先获得字符流
BufferedReader reader = request.getReader();
String str = reader.readLine();
// 直接获得username=zs
System.out.println(str);
}
}
- 字节流举例
/**
* 字节流
*/
@WebServlet("/body2")
public class BodyServlet2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// 首先获得字节流
ServletInputStream inputStream = request.getInputStream();
// 把里面的值保存到 D://tmp//body.txt
FileOutputStream fileOutputStream = new FileOutputStream("D:/body.txt");
int length = 0;
byte[] bytes = new byte[1024];
while((length = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes,0,length);
}
inputStream.close();
fileOutputStream.close();
}
}
特殊信息
获取客户机和服务器主机信息
- 请求是从客户机发到服务器的,在服务器中处理信息的获得,那么对于服务器,本地local是服务器,远程remote是客户机
- 在Servlet中可以获得本地的IP和Port,也可以获得远程IP和Port
信息 | 方法 | 返回值 |
---|---|---|
本地(服务器)IP | getLocalAddr() | String |
本地(服务器)端口号 | getLocalPort() | int |
远程(客户机)IP | getRemoteAddr() | String |
远程(客户机)端口号 | getRemotePort() | int |
eg:
/**
* 这里发送的请求是:localhost:8080/demo1/addr
* 192.168.XXX.XXX/demo/addr也可以同样访问
*/
@WebServlet("/addr")
public class AddrPortServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
String localAddr = request.getLocalAddr();
int localPort = request.getLocalPort();
String remoteAddr = request.getRemoteAddr();
int remotePort = request.getRemotePort();
System.out.println("come from " + remoteAddr + ": " + remotePort);
System.out.println("server is " + localAddr + ": " + localPort);
}
}
请求参数
请求参数的场景:
- 请求参数 在请求行中
getQueryString()
- 请求参数 在请求体中
getInputStream()/getReader()
- 指的是:
key=value&key=value
eg:
手动实现获取请求参数:
@WebServlet("/parameter")
public class ParameterServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// GET请求请求参数出现在请求行里
String parameterStr = null; // username=zs&password=ls
if ("GET".equals(request.getMethod())){
parameterStr = request.getQueryString();
}else if ("POST".equals(request.getMethod())) {
parameterStr = request.getReader().readLine();
}
// http://localhost:8080/demo1?username=zs&password=ls
// 能否解析请求参数以及所对应的值
if (parameterStr != null && !"".equals(parameterStr)) {
String[] parameterArray = parameterStr.split("\\&");
for (String parameter : parameterArray) {
System.out.println(parameter);
String parameterName = parameter.substring(0, parameter.indexOf("=")); //username=zs
String parameterValue = parameter.substring(parameter.indexOf("=") + 1); // password=ls
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
直接封装
实际开发中并不需要我们手动实现找出请求参数,因为Request已经帮我们封装了可以直接使用的方法了
request.getParameterXXX
这样的一些方法:
方法 | 返回值 | 说明 |
---|---|---|
getParameterNames() | Enumeration<String> | 获得所有的key |
getParameterMap() | Map<String,String[]> | 获得所有的请求参数 |
getParameter(String) | String | 获得第一个值 |
getParameterValues(String) | String[] | 获得所有值 |
- request对于请求参数的封装实际上,封装为一个
Map<String,String[]>
- eg:
username=zs&password=12345&hobby=sing&hobby=dance&hobby=rap&hobby=basketball
- eg:
eg:
/**
* 使用Request提供的方法来获取参数
* http://localhost:8080/demo1/parameter2
* ?username=zs&password=12345&hobby=sing&hobby=dance&hobby=rap&hobby=basketball
*
* 可以是GET请求,通过queryString的方式提供
* 也可以POST请求,通过请求体提供参数
*/
@WebServlet("/parameter2")
public class ParameterServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// 获取key值
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
String parameterValue = request.getParameter(parameterName);
System.out.println(parameterName + " = " + parameterValue);
/*
username = zs
password = 12345
hobby = sing
*/
String[] parameterValues = request.getParameterValues(parameterName);
System.out.println(parameterName + " = " + Arrays.asList(parameterValues));
/*
username = [zs]
password = [12345]
hobby = [sing, dance, rap, basketball]
*/
}
Map<String, String[]> parameterMap = request.getParameterMap();
Iterator<String> iterator = parameterMap.keySet().iterator();
while(iterator.hasNext()) {
String parameterName = iterator.next();
String[] parameterValues = parameterMap.get(parameterName);
}
}
}
引用类型
http://localhost:8080/demo1/parameter4/register?
username=bob&password=123456&age=21&birthday=2004-01-16&mobile=18801106688
- 将请求参数封装为一个引用类型的对象
案例(Servlet与Mybatis结合):
@Data
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private Date birthday;
private Date createDate;
private String mobile;
}
public interface UserMapper {
int insert(User user);
}
<mapper namespace="com.coo1heisenberg.demo1.mapper.UserMapper">
<insert id="insert">
insert into test_user(username, password, age, birthday, createDate, mobile)
values (#{username},#{password},#{age},#{birthday},#{createDate},#{mobile})
</insert>
</mapper>
@WebServlet("/parameter/register")
public class ParameterServlet3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);
// 这部分过于繁琐
User user = new User();
user.setUsername(request.getParameter("username"));
user.setPassword(request.getParameter("password"));
user.setAge(Integer.parseInt(request.getParameter("age")));
String birthdayStr = request.getParameter("birthday");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = dateFormat.parse(birthdayStr);
user.setBirthday(date);
} catch (ParseException e) {
e.printStackTrace();
}
user.setCreateDate(new Date());
user.setMobile(request.getParameter("mobile"));
userMapper.insert(user);
}
}
对上面的代码进行优化:
// 生成一个工具类
public class ParameterUtil {
private static final String DAY_FORMAT_PATTERN = "yyyy-MM-dd";
public static <T> T getInstance(Class<T> clazz, HttpServletRequest request)
throws Exception {
// 创建一个实例
T instance = clazz.newInstance();
// clazz里的成员变量名 与 请求参数名对应
Enumeration<String> parameterNames = request.getParameterNames(); // fieldNames
while (parameterNames.hasMoreElements()) {
// 获得请求参数的值
String parameterName = parameterNames.nextElement();
String parameterValue = request.getParameter(parameterName);
// 获得成员变量
Field field = clazz.getDeclaredField(parameterName);
field.setAccessible(true);
if (field.getType() == Integer.class) {
Integer integerParameterValue = Integer.parseInt(parameterValue);
field.set(instance, integerParameterValue);
} else if (field.getType() == Date.class) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DAY_FORMAT_PATTERN);
Date date = simpleDateFormat.parse(parameterValue);
field.set(instance, date);
} else {
// 给成员变量赋值
field.set(instance, parameterValue);
}
}
return instance;
}
}
@WebServlet("/parameter4/register")
public class ParameterServlet4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) {
UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);
User user = null;
try {
user = ParameterUtil.getInstance(User.class, request);
user.setCreateDate(new Date());
} catch (Exception e) {
e.printStackTrace();
}
userMapper.insert(user);
}
}
- BeanUtils
- 第三方工具类,作用和上面自己写的工具类性质一样
- 引入依赖
commons-beanutils
- 这个工具类
Date
转换不了
BeanUtils.copyProperties(instance, parameterMap);//直接使用其提供的copyProperties方法
eg:
@WebServlet("/parameter5/register")
public class ParameterServlet5 extends HttpServlet {
@SneakyThrows
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) {
UserMapper userMapper = MybatisUtil.getSqlSession().getMapper(UserMapper.class);
User user = new User();
Map<String, String[]> parameterMap = request.getParameterMap();
BeanUtils.copyProperties(user,parameterMap);
userMapper.insert(user);
}
}
POST请求请求参数乱码
乱码问题:编解码不一致
eg:
<body>
<h1>GET请求</h1>
<form action="/demo1/parameter/encoding" method="get">
<input name="username"><input type="submit">
</form>
<h1>POST请求</h1>
<form action="/demo1/parameter/encoding" method="post">
<input name="username"><input type="submit">
</form>
</body>
/**
* 这次测试:username="张三"
*/
@WebServlet("/parameter/encoding")
public class ParameterEncodingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("username = " + username);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
// 需要设置转码
request.setCharacterEncoding("utf-8");
// 控制台出现:username = ??????
String username = request.getParameter("username");
System.out.println("username = " + username);
}
}
文件上传
- 创建
form
表单
注册用户信息
<form action="/parameter/file" enctype="multipart/form-data" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
年龄:<input type="text" name="age"><br>
<!--头像上传-->
<!--要提交文件要加上 enctype="multipart/form-data"-->
头像:<input type="file" name="avatar"><br>
<input type="submit">
</form>
- 发送请求通过fiddler抓取
POST http://localhost:8080/parameter/file HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 167653
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary8bJUh6YXwtkxIifX
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:8080/demo1/file.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: Pycharm-89c7dd8b=47f9fb69-6795-467d-875b-0a44c63e1e97; Idea-75c3c9a=b19ee743-c677-4bab-b7bd-673c42a25ce0
<!--这里是普通的请求信息-->
------WebKitFormBoundary8bJUh6YXwtkxIifX
Content-Disposition: form-data; name="username"
zs
------WebKitFormBoundary8bJUh6YXwtkxIifX
Content-Disposition: form-data; name="password"
123456
------WebKitFormBoundary8bJUh6YXwtkxIifX ---> 这是分隔符
Content-Disposition: form-data; name="age"
25
<!--这里是文件的请求信息-->
------WebKitFormBoundary8bJUh6YXwtkxIifX
Content-Disposition: form-data; name="avatar"; filename="1.jpg"
Content-Type: image/jpeg
<!--这里是图片的字节数据-->
JFIF H H 1lPhotoshop 3.0 8BIM Z %G t 8BIM% T vN ( Ǹ 8BIM:
printOutput PstSbool Inteenum Inte Img printSixteenBitbool
printerNameTEXT printProofSetupObjc h!h7 n
proofSetup Bltnenum builtinProof proofCMYK 8BIM; - printOutputOptions Cptnbool Clbrbool RgsMbool CrnCbool CntCbool Lblsbool Ngtvbool EmlDbool Intrbool BckgObjc RGBC Rd doub@o Grn doub@o Bl doub@o BrdTUntF#Rlt Bld UntF#Rlt RsltUntF#Pxl@R
vectorDatabool PgPsenum PgPs PgPC LeftUntF#Rlt Top UntF#Rlt Scl UntF#Prc@Y cropWhenPrintingbool cropRectBottomlong cropRectLeftlong
cropRectRightlong
cropRectToplong 8BIM H H 8BIM& ? 8BIM
8BIM 8BIM 8BIM'
8BIM H /ff lff /ff 2 Z 5 - 8BIM p 8BIM @ @ 8BIM 8BIM 9 @ 1 8 @ null boundsObjc Rct1 Top long Leftlong Btomlong Rghtlong @ slicesVlLs Objc slice sliceIDlong groupIDlong originenum ESliceOrigin
autoGenerated Typeenum
ESliceType Img boundsObjc Rct1 Top long Leftlong Btomlong Rghtlong @ urlTEXT nullTEXT MsgeTEXT altTagTEXT cellTextIsHTMLbool cellTextTEXT horzAlignenum ESliceHorzAlign default vertAlignenum ESliceVertAlign default
bgColorTypeenum ESliceBGColorType None topOutsetlong
leftOutsetlong bottomOutsetlong
rightOutsetlong 8BIM( ? 8BIM 8BIM 8BIM ( x (m XICC_PROFILE HLino mntrRGB XYZ 1 acspMSFT IEC sRGB -HP cprt P 3desc lwtpt bkpt rXYZ gXYZ , bXYZ @ dmnd T pdmdd vued L view $lumi meas $tech 0 rTRC < gTRC < bTRC < text Copyright (c) 1998 Hewlett-Packard Company desc sRGB IEC61966-2.1 sRGB IEC61966-2.1 XYZ Q XYZ XYZ o 8 XYZ b XYZ $ desc IEC http://www.iec.ch IEC http://www.iec.ch desc .IEC 61966-2.1 Default RGB colour space - sRGB .IEC 61966-2.1 Default RGB colour space - sRGB desc ,Reference Viewing Condition in IEC61966-2.1 ,Reference Viewing Condition in IEC61966-2.1 view _.
\ XYZ L V P W meas sig CRT curv
# ( - 2 7 ; @ E J O T Y ^ c h m r w |
%+28>ELRY`gnu| &/8AKT]gqz
!-8COZfr~ -;HUcq~
+:IXgw '7HYj{ + = O a t
2FZn % : O d y
- 使用Request中的
getPart
方法直接拿到其图片部分Part getPart(String var1) throws IOException, ServletException;
- 使用
getPart
方法注意加注解@MultipartConfig
- 获得Part对象,通过Part中提供的方法可以获得其他具体的信息:
方法 | 返回值 | 说明 |
---|---|---|
getInputStream() | InputStream | 获得字节输入流,可以读取字节数据将其保存下来 |
getContentType() | String | 获得正文类型,比如png图片,其值为image/png |
getSize() | long | 获得文件字节大小 |
getName() | String | 获得请求参数名(这里就是avatar) |
getSubmittedFileName() | String | 获得上传的原始文件名(这里是1.jpg) |
eg:
@MultipartConfig
@WebServlet("/parameter/file")
public class ParameterFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
Part usernamePart = request.getPart("username");
Part avatarPart = request.getPart("avatar");
InputStream inputStream = avatarPart.getInputStream();
// 保存在D://下XXX.jpg
FileOutputStream OutputStream = new FileOutputStream("D:\\1.jpg");
int length = 0;
byte[] bytes = new byte[1024];
while ((length = inputStream.read(bytes) )!= -1) {
OutputStream.write(bytes,0,length);
}
inputStream.close();
OutputStream.close();
}
}
案例(与前面的getServletContext
结合)
- 保存文件到指定位置,文件位置由配置文件提供
application.properties
pic.path=D://tmp
PropertiesInitiationlize.java
@WebServlet(value = "/properties", loadOnStartup = 1)
public class PropertiesInitializationServlet extends HttpServlet {
@SneakyThrows
@Override
public void init() throws ServletException {
ServletContext servletContext = getServletContext();
Properties properties = new Properties();
properties.load(PropertiesInitializationServlet
.class.getClassLoader().getResourceAsStream("application.properties"));
String value = properties.getProperty("pic.path");
servletContext.setAttribute("picPath",value);
}
}
ParameterFile.java
@MultipartConfig
@WebServlet("/parameter/file")
public class ParameterFileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
Part usernamePart = request.getPart("username");
Part avatarPart = request.getPart("avatar");
String submittedFileName = avatarPart.getSubmittedFileName();
InputStream inputStream = avatarPart.getInputStream();
// 保存在D://下XXX.jpg
//FileOutputStream OutputStream = new FileOutputStream("D:\\1.jpg");
// 保存在指定位置,上传时的文件名叫什么,保存时候的文件名就叫什么
String picPath = (String) getServletContext().getAttribute("picPath");
File file = new File(picPath, submittedFileName);
FileOutputStream outputStream = new FileOutputStream(file);
int length = 0;
byte[] bytes = new byte[1024];
while ((length = inputStream.read(bytes) )!= -1) {
outputStream.write(bytes,0,length);
}
inputStream.close();
outputStream.close();
}
}
Request做请求的转发
- 现在使用很少
- 是用来转发的两个请求之间的数据共享
- Request域可以用来转发的请求之间数据共享
request.setAttribute
request.getAttribute
- Request域可以用来转发的请求之间数据共享
eg:
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("servlet1");
// 由Request提供的数据共享的空间
request.setAttribute("username","zs");
request.getRequestDispatcher("/servlet2").forward(request,resp);
}
}
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException {
Object username = request.getAttribute("username"); // 这个username就是zs
System.out.println("servlet2");
}
}
当上面的代码执行http://localhost:8080/demo1/servlet1
的同时会执行/servlet2
,可以用来共享数据