06_Request

文章目录

  • 前置知识点
    • 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
    • 携带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、GETgetMethod()String获得请求方法
URLhttp://101.43.69.31:8083/admin/auth/logingetRequestURL()StringBuffer获得请求URL
URI/admin/auth/login、/demo3/hellogetRequestURI()String获得请求URI
context-path/demo3getContextPath()String获得上下文
服务器ip101.43.69.31、localhostgetLocalAddr()String获得ip
端口号8083、8080getLocalPort()int获得端口号
QueryStringusername=zhangsangetQueryString()String获得Get请求的查询字符串
协议HTTP/1.1getProtocol()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
信息方法返回值
本地(服务器)IPgetLocalAddr()String
本地(服务器)端口号getLocalPort()int
远程(客户机)IPgetRemoteAddr()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:

/**
 * 使用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

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,可以用来共享数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/492566.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pip安装pyqt5报错

已解决pip安装pyqt5报错 ERROR: Could not build wheels for PyQt5-sip, which is required to install pyproject.toml-based projects 安装C生成工具

查询 in条件下按顺序排序

查询语句 select * from user where id in (5,21,6);查询结果是不是按照参数顺序排列的&#xff0c;为了保证查询顺序可以使用 select * from sj_user where id in(5,21,6) order by FIELD(id,5,21,6); //或者 select * from sj_user where id in(5,21,6) order by FIND_IN_S…

MFC标签设计工具 图片控件上,移动鼠标显示图片控件内的鼠标xy的水平和垂直辅助线要在标签模板上加上文字、条型码、二维码 找准坐标和字体大小 源码

需求&#xff1a;要在标签模板上加上文字、条型码、二维码 找准坐标和字体大小 我生成标签时&#xff0c;需要对齐和 调文字字体大小。这工具微调 能快速知道位置 和字体大小。 标签设计(点击图片&#xff0c;上下左右箭头移动 或-调字体) 已经够用了&#xff0c;滚动条还没完…

使用docker-compose搭建wordpress博客

1、从远程仓库拉取worldpress镜像到本地 2、新建一个项目&#xff0c;然后在新建的项目目录里面新建一个docker-compose.yml模版文件。 3、编写docker-compose.yml文件 4、docker-compose up 运行项目。 5、在浏览器测试 使用docker-compose搭建wordpress博客实验成功。

过滤器 Filter

目录 1、Filter是什么 2、原理 3、怎样使用 步骤&#xff1a; Filter的执行流程&#xff1a; 拦截路径配置&#xff1a; 配置方式&#xff1a; 过滤器链&#xff1a; 1、Filter是什么 Filter是一个在计算机中用于筛选、过滤和修改数据的组件或模块。它在数据传输和处理…

python入门题:输入输出练习

以下是Python基础语法的练习&#xff0c;项目要求和代码如下&#xff1a; """ 例3&#xff1a;小精灵&#xff1a;你好&#xff0c;欢迎古灵阁&#xff0c;请问您需要帮助吗&#xff1f;需要or不需要&#xff1f; 你&#xff1a;需要 小精灵&#xff1a;请问你需…

python 中判断文件、目录是否存在的方法

判断目录是否存在并创建目录 一、实现上传文件功能二、判断目录是否存在的办法2.1、使用os模块2.1.1、判断目录是否存在2.1.2、os.makedirs()&#xff1a;递归创建目录 2.2、使用pathlib模块2.2.1、path.exist()判断目录是否存在2.2.1、path.mkdir()&#xff1a;创建目录 2.3、…

深入聊聊企业数字化转型这个事儿

01 什么是数字化&#xff1f; 聊数字化&#xff0c;就不得不聊聊信息化、智能化。佛性的说&#xff1a;信息化是数字化的前世&#xff0c;智能化是数字化的来生&#xff01;我习惯用一个结构化的图形来表示事物之间的关系&#xff0c;信息化、数字化、智能化的关系如下&#…

后端基础篇- 社区 IDEA 手动 Maven 创建 SpringBoot 项目、Maven 安装与配置环境变量、IDEA 集成 Maven

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Maven 安装与配置环境变量 1.1 下载并解压安装包 1.2 配置本地仓库 1.3 配置阿里云私服 1.4 配置环境变量 2.0 IDEA 集成 Maven 2.1 首先创建一个新项目 2.2 开始…

Unity编辑器功能 将选中的文件夹复制一份到其他文件夹

[MenuItem("Ab包工具/将选中的文件移动到StreamingAssets文件夹下")] public static void MoveFireToStreamA() { //得到选中文件的数组 Object[] selectobj Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); i…

【数据结构初阶】之堆(C语言实现)

数据结构初阶之堆&#xff08;C语言实现&#xff09; &#x1f30f; 堆的概念&#x1f30f; 堆的模拟实现&#x1f413; 堆的结构和方法接口&#x1f413; 堆的方法的模拟实现&#x1f64a; 堆的初始化&#x1f64a; 堆的构建&#x1f64a; 堆的插入&#x1f64a; 向上调整&…

sentinel热点参数流控

1、概念 热点参数限流会统计传入参数中的热点参数&#xff0c;并根据配置的限流阈值与模式&#xff0c;对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制&#xff0c;仅对包含热点参数的资源调用生效。 2、示例 2.1、目的 对于如下的/get接口的参…

【正点原子FreeRTOS学习笔记】————(13)队列集

这里写目录标题 一、队列集简介&#xff08;了解&#xff09;二、队列集相关API函数介绍&#xff08;熟悉&#xff09;三、队列集操作实验&#xff08;掌握&#xff09; 一、队列集简介&#xff08;了解&#xff09; 一个队列只允许任务间传递的消息为同一种数据类型&#xff…

鸿蒙开发之了解ArkTS

鸿蒙开发者官网 &#xff1a; https://developer.huawei.com/consumer/cn/ 开发鸿蒙要用的软件是 DevEco Studio ArkTS建立在JS和TS的基础之上&#xff0c;扩展了声明式UI开发范式和状态管理&#xff0c;提供更简洁和自然的开发方式。 ArkTS引入了渲染引擎的增强&#xff0c…

centos7 linux下yum安装redis

安装redis 1.检查是否有redis yum 源 yum install redis2.下载fedora的epel仓库 yum install epel-release3.安装redis数据库 yum install redis4.安装完毕后&#xff0c;使用下面的命令启动redis服务 # 启动redis service redis start# 停止redis service redis stop# 查…

UOS、Linux下的redis的详细部署流程(适用于内网)

提示&#xff1a;适用于Linux以及UOS等内外网系统服务器部署。 文章目录 一.上传离线包二.部署基本环境三.解压并安装redis四.后台运行redis五.uos系统可能遇到的问题六.总结 一.上传离线包 1.自己去Redis官网下载适配自己部署系统的redis安装包。 2.通过文件传输工具&#xf…

精酿啤酒屋:畅饮与文化的交汇点

在城市的繁华之中&#xff0c;Fendi Club啤酒屋犹如一颗璀璨的明珠&#xff0c;吸引着无数寻求文化与享受的人们。它不仅仅是一个提供美酒佳肴的地方&#xff0c;更是一个文化和社交的交汇点。 走进Fendi Club&#xff0c;你会被它与众不同的环境所吸引。暗色调的装饰风格&…

Python机器学习赋能GIS:地质灾害风险评价的新方法论

地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下&#xff0c;地质灾害在世界范围内频繁发生。我国除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉…

NO11 蓝桥杯单片机之DS18B20数字温度计

DS18B20数字温度计这个模块和以往单片机学习的模块可能不同&#xff0c;这里还要知道其头文件&#xff08;.h&#xff09;和.c文件代码的理解。 具体这个温度计是怎么实现检测温度的&#xff0c;呃呃呃呃呃这可能就要去查阅专业资料&#xff0c;涉及的知识体系应该很庞大&…

ABNDP: Co-optimizing Data Access and Load Balance in Near-Data Processing——论文泛读

ASPLOS 2023 Paper 论文阅读笔记整理 问题 近数据处理&#xff08;NDP&#xff09;是一种很有前途的体系结构范式&#xff0c;可以解决数据密集型应用程序的内存墙挑战。基于3D堆叠存储器的典型NDP系统包含大量并行处理单元&#xff0c;每个并行处理单元都可以访问其本地存储…