06_Request

news2024/10/7 16:18:00

文章目录

  • 前置知识点
    • 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,可以用来共享数据

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PTA-练习9

目录 实验10-4 递归实现顺序输出整数 实验10-10 十进制转换二进制 实验10-6 递归求简单交错幂级数的部分和 实验11-1-2 输出月份英文名 实验11-1-6 指定位置输出字符串 实验11-1-8 查找子串 递归的基本思路&#xff1a; 推出递归的条件或者进入递归的条件每层递归需要执行…

JavaScript 打印教程(第二部分)设置编码

JavaScript 打印教程&#xff08;第二部分&#xff09;设置编码 在进行文本打印时&#xff0c;尤其是涉及到中文或其他特殊字符时&#xff0c;正确的编码设置是非常重要的。不同的打印机支持不同的指令集&#xff0c;因此了解并使用适合您打印机的指令集是关键。本篇教程继续使…

07、JS实现:用回溯法实现数组全排列的算法(一步一步剖析,很详细)

回溯法实现数组全排列的算法 Ⅰ、回溯法实现数组全排列&#xff1a;1、题目描述&#xff1a;2、解题思路&#xff1a;3、实现代码&#xff1a; Ⅱ、小结&#xff1a; Ⅰ、回溯法实现数组全排列&#xff1a; 1、题目描述&#xff1a; 给定⼀个 没有重复 数字的序列&#xff0c;…

DBeaver修改sql语句保存位置

1、dbeaver通过工作空间方式来管理Script的sql脚本以及数据库连接。 工作空间&#xff0c;其实也就是一个文件夹 默认保存路径查看&#xff1a; 文件--> 切换工作空间 --> 其他 sql脚本的保存位置默认在工作空间下的 \General\Scripts 文件夹中。 2、 3、点击浏览&#…

海外业务运营 别让资金支出管控成为开疆拓土的“绊脚石”

据《中国企业出海信心报告》显示,超六成企业有海外业务拓展计划。成熟出海企业将把目光放至新市场,新锐出海企业更聚焦新业务线的开辟。其中,当属高端制造业的出海步伐“迈得早”、“迈得大”。 高端制造业主要包含医药制造业,通用设备制造业,专用设备制造业,汽车制造业,通信设…

如何用Flask中的Blueprints构建大型Web应用

本文分享自华为云社区《构建大型Web应用Flask中的Blueprints指南》&#xff0c;作者&#xff1a; 柠檬味拥抱。 什么是Blueprints&#xff1f; 什么是Blueprints&#xff1f; Blueprints是Flask中的一种模式&#xff0c;用于将应用程序分解为可重用的模块。每个蓝图实际上是…

23届嵌入式被裁,有什么好的就业建议?

最近看到了一个提问&#xff0c;原话如下&#xff1a; 本人23届毕业生&#xff0c;就业方向嵌入式软件&#xff0c;坐标深圳&#xff0c;工作3月公司裁员&#xff0c;目前接近12月开始找工作。 boss上投递简历&#xff0c;校招岗&#xff0c;比较有规模的好公司基本已读不回&am…

浅析扩散模型与图像生成【应用篇】(十二)——DiffI2I

12. DiffI2I: Efficient Diffusion Model for Image-to-Image Translation 该文提出一种基于扩散模型的图像到图像的转换算法&#xff08;DiffI2I&#xff09;,可用于图像修复、超分辨率提升、图像去模糊、语义分割等任务。作者指出一般的扩散模型&#xff0c;虽然在图像生成任…

C++STL学习之unordered_map与unordered_set(底层Hash)

前言&#xff1a;我们前面已经学习论map和set&#xff0c;现在又冒出来一个unordered_map和unordered_set&#xff0c;这两个有啥差别吗&#xff1f;前面我们已经说过&#xff0c;map和set的底层是红黑树&#xff0c;那unordered_map和unordered_set的底层是什么呢&#xff1f;…

基于nodejs+vue“共享书角”图书借还管理系统python-flask-django-php

同时还能为借阅者提供一个方便实用的“共享书角”图书借还管理系统&#xff0c;使得借阅者能够及时地找到合适自己的图书借还信息。管理员在使用本系统时&#xff0c;可以通过后台管理员界面管理借阅者的信息&#xff0c;也可以发布系统公告&#xff0c;让借阅者及时了解图书借…

免杀对抗-C2远控篇CC++SC转换格式UUID标识MAC物理IPV4地址减少熵值

参考文章&#xff1a; https://github.com/INotGreen/Bypass-AMSI https://mp.weixin.qq.com/s/oJ8eHdX8HGuk6dZv0kmFxg https://kyxiaxiang.github.io/2022/12/14/AMSIandEtw https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell 文章参考&#xff1a; https://www.…

Go——结构体

Go语言中没有类的概念&#xff0c;也不支持类的继承等面向对象的概念。Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。 一. 类型别名和自定义类型 1.1 自定义类型 在Go语言中有一些基本的数据类型&#xff0c;如string&#xff0c;整型&#xff0c;…

YOLOv9改进策略:block优化 | SEAM提升小目标遮挡物性能

&#x1f4a1;&#x1f4a1;&#x1f4a1;本文改进内容&#xff1a;SEAM提升小目标遮挡物性能&#xff0c;在多个数据集得到很好的验证 改进结构图如下&#xff1a; YOLOv9魔术师专栏 ☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️☁️ ☁️☁️☁️…

docker学习笔记 四-----docker基本使用方法

基础命令奉上&#xff1a; 1、docker命令查询方法 docker --help 获取docker命令帮助 docker search --help 查询docker 子命令search的帮助 2、查询镜像 查询镜像 docker search 192.168.206.100:5000/mysql 查询指定服务器指定镜像 docker search mysql …

Qt Design Studio各个组件怎么用?【长期更新】

写在前面&#xff1a;本文长期更新&#xff0c;建议点赞/收藏/关注~ 在Qt Design Studio中&#xff0c;组件类别有&#xff1a; 每一种&#xff0c;都有其特定的用途和适用场景&#xff1a; 1.My Components 使用时机&#xff1a;当你需要重用自定义的设计元素或者特殊功能…

【wallabag】数字化阅读时代的救星——wallabag来了!

为什么需要 ✨在海量信息涌动的时代&#xff0c;一篇好文章却总是在最不恰当的时候出现。想要留住精彩内容&#xff0c;却苦于当下分身乏术&#xff1f;墙裂推荐你试试wallabag&#xff0c;这款智能稍后阅读神器&#xff0c;让你随时随地畅享深度阅读的乐趣&#xff01; Walla…

2024第六届环境科学与可再生能源国际会议能源 (ESRE 2024) 即将召开!

2024第六届环境科学与可再生能源国际会议 能源 &#xff08;ESRE 2024&#xff09; 即将举行 2024 年 6 月 28 日至 30 日在德国法兰克福举行。ESRE 2024 年 旨在为研究人员、从业人员和专业人士提供一个论坛 从工业界、学术界和政府到研究和 发展&#xff0c;环境科学领域的专…

Altair(澳汰尔) Radioss® 评估和优化动态载荷下的高度非线性问题

Altair&#xff08;澳汰尔&#xff09; Radioss 评估和优化动态载荷下的高度非线性问题 Radioss 是一款超前的分析解决方案&#xff0c;可评估和优化动态载荷下的高度非线性问题。它广泛应用于全球各行各业&#xff0c;能有效提高复杂设计的耐撞性、安全性和可制造性。 30 多…

VRAY渲染设置大神参数(建议收藏)

3dmax效果图云渲染平台——渲染100以3ds Max 2024、VR 6.2、CR 11.2等最新版本为基础&#xff0c;兼容fp、acescg等常用插件&#xff0c;同时LUT滤镜等参数也得到了同步支持。注册填邀请码【7788】可领30元礼包和免费渲染券哦~ 公用&#xff1a;输出大小&#xff1a;一般小图50…

数据结构-----栈、顺序栈、链栈

在软件应用中&#xff0c;栈这种后进先出数据结构的应用是非常普遍的。比如用浏览器上网时&#xff0c;不管什么浏览器都有一个“后退”键&#xff0c;你点击后可以按访问顺序的逆序加载浏览过的网页。即使从一个网页开始&#xff0c;连续点了几十个链接跳转&#xff0c;你点“…