<7>HttpServletRequest 类

本文详细介绍了HttpServletRequest在Servlet中的作用,包括常用方法如获取请求URI、URL、客户端IP、请求头、参数等。通过代码实例展示了如何获取表单数据,并针对GET、POST请求的中文乱码问题提供了处理方法。在GET请求中,需先以ISO8859-1编码再用UTF-8解码;在POST请求中,需设置请求体的字符集为UTF-8。

1.HttpServletRequest 类的作用

  每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。 然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。

2.HttpServletRequest 类的常用方法

  • getRequestURI()   获取请求的资源路径
  • getRequestURL()   获取请求的统一资源定位符(绝对路径)
  • getRemoteHost()   获取客户端的 ip 地址 iv. getHeader() 获取请求头
  • getParameter()   获取请求的参数
  • getParameterValues()   获取请求的参数(多个值的时候使用)
  • getMethod()   获取请求的方式 GET 或 POST
  • setAttribute(key, value);   设置域数据
  • getAttribute(key);   获取域数据
  • getRequestDispatcher()   获取请求转发对象

2.1.HttpServletRequest 类的常用方法代码实例

public class HelloServlet03 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        // getRequestURI() 获取请求的资源路径
        String requestURI = req.getRequestURI();
        System.out.println("URI => " +requestURI);
        
        // getRequestURL() 获取请求的统一资源定位符(绝对路径)
        StringBuffer requestURL = req.getRequestURL();
        System.out.println("URL => " +requestURL);

//        getRemoteHost() 获取客户端的 ip 地址
        String remoteHost = req.getRemoteHost();
        System.out.println("客户端 ip 地址 => " +remoteHost);

        // getHeader() 获取请求头
        System.out.println("请求头 User-Agent ==>> " + req.getHeader("User-Agent"));
        // getMethod() 获取请求的方式 GET 或 POST
        System.out.println( "请求的方式 ==>> " + req.getMethod() );
    }
}

实验结果:
在这里插入图片描述

2.2.获取表单数据

很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。
例,表单为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/06_servlet/HelloServlet03" method="get">
    用户名:<input type="text" name="username"><br/>
    密码:<input type="password" name="password"><br/>
    兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
    <input type="checkbox" name="hobby" value="java">Java
    <input type="checkbox" name="hobby" value="js">JavaScript<br/>
    <input type="submit">
</form>
</body>
</html>

Java 代码:

public class HelloServlet03 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String[] hobbies = req.getParameterValues("hobby");

        System.out.println("用户名:" + username);
        System.out.println("密码:" + password);
        System.out.println("兴趣爱好:" + Arrays.asList(hobbies));
    }
}

2.3.解决GET、POST请求的中文乱码问题

doGet:

// 获取请求参数 
String username = req.getParameter("username");
 //1 先以 iso8859-1 进行编码 
 //2 再以 utf-8 进行解码 
username = new String(username.getBytes("iso-8859-1"), "UTF-8");

doPost:

// 设置请求体的字符集为 UTF-8,从而解决 post 请求的中文乱码问题 
req.setCharacterEncoding("UTF-8");
我连构建都过不去C:\Users\lanke\Downloads\20251116141133\AgedCare\agedcare-modules\agedcare-modules-clientShare\src\main\java\com\agedcare\clientshare\im\aspect\RepeatSubmitAspect.java:69:100 java: 不兼容的型: javax.servlet.http.HttpServletRequest无法转换为jakarta.servlet.http.HttpServletRequest<?xml version="1.0" encoding="UTF-8"?> <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.agedcare</groupId> <artifactId>agedcare-modules</artifactId> <version>3.6.6</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>agedcare-modules-clientShare</artifactId> <description> agedcare-modules-clientShare 客户端共享模块 </description> <dependencies> <!-- SpringCloud Alibaba Nacos --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- SpringCloud Alibaba Nacos Config --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- SpringCloud Alibaba Sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- SpringBoot Actuator --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!-- Mysql Connector --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> </dependency> <!-- AgedCare Common DataSource --> <dependency> <groupId>com.agedcare</groupId> <artifactId>agedcare-common-datasource</artifactId> </dependency> <!-- AgedCare Common Log --> <dependency> <groupId>com.agedcare</groupId> <artifactId>agedcare-common-log</artifactId> </dependency> <!-- AgedCare Common Swagger --> <dependency> <groupId>com.agedcare</groupId> <artifactId>agedcare-common-swagger</artifactId> </dependency> <!-- Jackson Datatype Joda --> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> </dependency> <!-- SpringCloud Openfeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- MyBatis Plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <!-- AgedCare System Api --> <dependency> <groupId>com.agedcare</groupId> <artifactId>agedcare-api-system</artifactId> <version>3.6.6</version> </dependency> <!-- AgedCare IM Client --> <dependency> <groupId>com.agedcare</groupId> <artifactId>agedcare-modules-imClient</artifactId> <version>3.6.6</version> </dependency> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <!-- 匹配 Spring Boot 3.x --> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <id>enforce-jakarta</id> <!-- 添加执行ID --> <goals><goal>enforce</goal></goals> <configuration> <rules> <bannedDependencies> <excludes> <exclude>javax.servlet:*</exclude> </excludes> <message>禁止使用 javax.servlet,必须迁移到 jakarta</message> </bannedDependencies> </rules> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
最新发布
11-24
<think> 我们面对的问题是在构建项目时出现“javax.servlet.http.HttpServletRequest 无法转换为 jakarta.servlet.http.HttpServletRequest”的错误。这通常是由于项目中同时存在javax.servlet和jakarta.servlet的依赖,或者代码在迁移到Jakarta EE 9+时未完全更新导致的。 从之前的构建输出中,我们看到项目`agedcare-gateway`依赖了`javax.servlet:servlet-api:2.5`,而`agedcare-modules-clientShare`依赖了`jakarta.servlet:jakarta.servlet-api:6.0.0`。这种混合依赖会导致型转换错误,因为它们是两个不同的包(javax.servlet和jakarta.servlet)。 解决思路: 1. **排除所有javax.servlet依赖**:确保项目中不再有javax.servlet的依赖。 2. **统一使用Jakarta Servlet API**:将所有使用到servlet的地方升级到Jakarta EE 9+的版本(即jakarta.servlet)。 3. **更新代码**:将代码中所有`import javax.servlet`改为`import jakarta.servlet`。 具体步骤: ### 1. 排除javax.servlet依赖 在Maven项目中,我们可以通过`<exclusions>`来排除传递依赖,或者直接移除对javax.servlet的依赖。 在`agedcare-gateway`模块中,我们看到它依赖了`pro.fessional:kaptcha:2.3.3`,而该库又依赖了`javax.servlet:servlet-api:2.5`。因此,我们需要在该依赖中排除这个servlet-api。 修改`agedcare-gateway`的pom.xml: ```xml <dependency> <groupId>pro.fessional</groupId> <artifactId>kaptcha</artifactId> <version>2.3.3</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </exclusion> </exclusions> </dependency> ``` 同时,检查项目其他模块是否直接或间接引入了javax.servlet的依赖,使用`mvn dependency:tree -Dincludes=javax.servlet:*,jakarta.servlet:*`命令来查看,并排除所有javax.servlet的依赖。 ### 2. 添加Jakarta Servlet依赖 确保项目中统一使用Jakarta Servlet API。在需要servlet的模块中,添加: ```xml <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> ``` 注意:如果使用的是Spring Boot 3.x,它已经内置了Jakarta EE 9+的依赖,因此通常不需要显式添加这个依赖,除非需要特定版本。 ### 3. 更新代码 将代码中所有`import javax.servlet`和`import javax.servlet.http`替换为`import jakarta.servlet`和`import jakarta.servlet.http`。 例如,在Java文件中: ```java // 替换前 import javax.servlet.http.HttpServletRequest; // 替换后 import jakarta.servlet.http.HttpServletRequest; ``` 可以使用IDE的全局替换功能,或者使用Maven插件在构建时自动转换(如果代码量很大)。 ### 4. 检查其他依赖库的兼容性 确保项目中的所有依赖库都支持Jakarta EE 9+。例如,上面的`kaptcha`库可能不支持Jakarta EE,所以排除它的javax.servlet依赖后,我们还需要确认它是否能在Jakarta EE环境下工作。如果不能,可能需要寻找替代库或者自己升级该库。 ### 5. Maven编译器插件配置 确保Maven编译器插件使用正确的Java版本(至少Java 17,因为Spring Boot 3要求Java 17+): ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> </configuration> </plugin> ``` ### 6. 使用Maven Enforcer Plugin禁止javax.servlet 为了防止再次引入javax.servlet依赖,可以在父pom中配置maven-enforcer-plugin: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <id>enforce-jakarta</id> <goals><goal>enforce</goal></goals> <configuration> <rules> <bannedDependencies> <excludes> <exclude>javax.servlet:*</exclude> </excludes> <message>请使用Jakarta EE 9+的依赖(jakarta.servlet)</message> </bannedDependencies> </rules> </configuration> </execution> </executions> </plugin> ``` ### 7. 重新构建项目 执行以下命令重新构建项目: ```bash mvn clean install ``` 如果仍然出现转换错误,请再次检查依赖树,确保没有javax.servlet的依赖残留。 ### 相关问题 1. 如何检查Maven项目中是否存在冲突的依赖? 2. 如何将使用javax.servlet的老旧库迁移到Jakarta EE 9+? 3. Spring Boot 3.x对Jakarta EE的支持有哪些注意事项? 4. 在Maven中如何全局排除某个依赖? [^1]: [Java IDEA] 关于 javax.servlet.http.HttpServletRequest 报错解决方案 [^2]: 程序运行时出现 java.lang.NoSuchMethodError [^3]: maven 打包项目 ERROR javax.servlet.http </think> ### 解决 `javax.servlet.http.HttpServletRequest` 无法转换为 `jakarta.servlet.http.HttpServletRequest` 错误 #### 问题根源 该错误通常由以下原因导致: 1. **混合使用 Servlet 规范**:项目同时存在 `javax.servlet` (Java EE 8-) 和 `jakarta.servlet` (Jakarta EE 9+) 的依赖 2. **依赖冲突**:Maven 依赖树中包含不兼容的 Servlet API 版本 3. **代码未迁移**:源代码仍使用 `javax.servlet.*` 导入语句 #### 解决方案(分步操作) ##### 1. 统一 Servlet API 依赖 在父 POM 或模块 POM 中强制使用 Jakarta Servlet API: ```xml <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency> ``` ##### 2. 排除所有 javax.servlet 依赖 在父 POM 中添加全局排除规则: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement> ``` ##### 3. 代码迁移(关键步骤) 使用 IDE 的全局替换功能: 1. 替换所有 `import javax.servlet.*` → `import jakarta.servlet.*` 2. 替换所有 `import javax.servlet.http.*` → `import jakarta.servlet.http.*` 3. 检查 XML 配置文件中是否残留 `javax.servlet` 引用 ##### 4. 添加 Maven Enforcer 插件 防止引入不兼容依赖: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <id>ban-javax-servlet</id> <goals><goal>enforce</goal></goals> <configuration> <rules> <bannedDependencies> <excludes> <exclude>javax.servlet:*</exclude> </excludes> <message>必须使用 Jakarta EE 9+ 规范</message> </bannedDependencies> </rules> </configuration> </execution> </executions> </plugin> ``` ##### 5. 验证依赖树 执行命令检查是否完全排除 javax.servlet: ```bash mvn dependency:tree -Dincludes=javax.servlet:*,jakarta.servlet:* ``` 期望输出: ``` [INFO] \- jakarta.servlet:jakarta.servlet-api:jar:6.0.0:provided [INFO] 没有 javax.servlet 相关依赖 ``` #### 特殊情况处理 若依赖库未提供 Jakarta EE 版本,需添加适配层: ```java // 创建适配 package com.yourpackage.adapter; import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest as JavaxRequest; public class ServletAdapter { public static HttpServletRequest adapt(JavaxRequest request) { return new JakartaRequestWrapper(request); } private static class JakartaRequestWrapper implements HttpServletRequest { private final JavaxRequest delegate; // 实现所有接口方法,委托调用 delegate } } ``` #### 验证成功标准 1. 编译通过且无型转换错误 2. 运行时无 `NoClassDefFoundError` 或 `NoSuchMethodError` 3. 执行以下测试代码返回 Jakarta 版本: ```java @RestController public class ServletCheckController { @GetMapping("/servlet-version") public String check(HttpServletRequest request) { return "Servlet API: " + request.getClass().getPackageName(); // 应返回 jakarta.servlet } } ``` #### 相关问题 1. 如何将使用 Java EE 8 的第三方库迁移到 Jakarta EE 10? 2. Spring Boot 3 中如何处理 Servlet 过滤器的兼容性问题? 3. Tomcat 10 与 Jakarta EE 9+ 的配置有哪些注意事项? 4. Maven 多模块项目中如何统一管理 Servlet API 版本? 5. 如何检测项目中残留的 javax.servlet 引用?[^1][^2][^3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值