JavaEE精选-Request

简介: JavaEE精选-Request

ServletRequest

针对于请求报文的封装,JAVAEE规范制定的就是ServletRequest接口

我们在使用中绝大多数的情况都是使用HttpServletRequest

常用API

获取请求行

request.getmethod():获取请求的方法

request.getRequestURI():获取请求资源,/应用名/资源路径

request.getRequestURL():获取完整的访问的域名路径名

request.request.getProtocol():获取请求协议

获取请求头

request.getHeaderNames():获取请求头的key列表,类似迭代器

hasMoreElements():查看是否还有下一个元素

headerNames.nextElement():迭代

request.getHeader(headerName):获取请求头对应的value

Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()){
            String headerName = headerNames.nextElement();
            String headerValue = request.getHeader(headerName);
            System.out.println(headerName + ":" + headerValue);
        }

获取客户机和服务器主机的信息

request.getLocalAddr():获取服务器主机的地址

request.getLocalPort():服务器端口

request.getRemoteAddr():客户端地址

request.getRemotePort():客户端的端口

获取请求参数

只要提交的数据是key=value&key=value形式,那么都可以使用接下来介绍的API来获取请求参数,无论是在请求行还是请求体均适用

只能获取用=连接的键值对,并且多个键值对直接用&来连接

request.getParameter:获取单个参数的值

request.getParameterValues:获取多个参数的值,返回一个数组

request.getParameterNames():获取所有参数的key,返回一个 Enumeration,类似于迭代器,接下来只需循环迭代即可

Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String key = parameterNames.nextElement();
            String[] values = request.getParameterValues(key);
            if(values.length == 1){
                System.out.println(key + ":" + values[0]);
            }else {
                System.out.println(key + ":" + Arrays.toString(values));
            }
        }

获取请求体

request.getInputStream()

其他

req.getServletPath() = requestURI - 应用名 相当于是获取资源的相对路径名
req.getContextPath() //获取应用名

封装数据到对象

JavaBean的特征:

1.一定要有无参构造函数

2.成员变量必须是private

3.一定要提供public的get和set方法

使用反射来手动获取并封装

package com.fh.ServletReq;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Enumeration;
//通过反射获取请求参数并封装到对象
@WebServlet("/ref")
public class GetParamServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Class<?> user = null;
        User u = null;
        try {
            user = Class.forName("com.fh.ServletReq.User"); //获取字节码文件
            u = (User) user.newInstance(); //实例化
        } catch (Exception e) {
            e.printStackTrace();
        }
        //首先得拿到请求参数的key和value
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            String[] values = req.getParameterValues(key);
            String upKey = key.substring(0, 1).toUpperCase() + key.substring(1); //key就是用来封装的方法的名字,将首字母大写
            try {
                Method set = user.getDeclaredMethod("set" + upKey, String.class);//调用set方法,这里一定要注意参数列表需要匹配
                if (values.length == 1) { //当values长度为1时,直接放入
                    set.invoke(u, values[0]);
                } else { //长度大于1需要使用StringBuilder来拼接
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < values.length; i++) {
                        if (i == values.length - 1) {
                            sb.append(values[i]);
                        } else {
                            sb.append(values[i]).append(",");
                        }
                    }
                    String s = sb.toString();
                    set.invoke(u, s);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println(u);
    }
}

使用工具类commons-beanutils

此时注意如果要使用第三方jar包,那么需要对EE项目进行配置,主要有两种方案

1.直接将jar包赋值到web的WEB-INF目录下,这样项目可以通过快速通道复制到根目录下

2.在Artifacts下新建一个lib文件夹,并将idea目录下的lib添加进去

package com.fh.ServletReq;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@WebServlet("/reg2")
public class RegServlet2 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = new User();
        try {
            BeanUtils.populate(user,req.getParameterMap());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(user);
    }
}

Debug

排查的过程:

1.查看状态码,如果是500,那么肯定表示代码出错了,但是如果没有出现500,不能说明没有错误

2.查看server(output)和localhost log,看看有无错误信息

3.具体去分析哪行代码出现了问题(仔细去查找,找和你的代码相关的部分)

在EE阶段要使用执行后续所有代码的按钮才能使页面正常响应

中文乱码问题

中文是否乱码要以debug的结果为准,不要看控制台的结果。

客户端发送的HTTP请求报文是UTF-8格式

请求报文被解析成为request对象之后,乱码了,解析的时候,解码用的不是utf-8 用的是ISO-8859-1 不支持中文

使用request.setCharacterEncoding来解决

注意事项:

1.只针对请求体有效

2.必须要在读取请求参数之前调用,也就是调用request.getParameter之前才可以使用

一般放在第一行,不容易出错

中文乱码只是在使用post请求方式时有乱码问题,如果使用get请求方式没有问题。前提是用的utf-8

网络路径总结

网络路径是指网络访问过程中的输入路径,与硬盘的路径有区别

全路径:htttp://localhost/app/1.html

可读性比较好,但在开发的过程中域名可能不同

相对路径:相对于当前页面的路径

比如提交的表单页面:http://localhost/app/1.html,里面的form表单的提交地址是

http://localhost/app/upload

那么写成相对路径就可以相对于1.html出发,去掉1.html然后再拼接上最终的路径

这种方式不灵活,不推荐

/开头的路径(推荐):

/应用名/资源路径。浏览器会自行补充访问协议、主机、端口号

转发

应用场景:

比如点击登录按钮,请求交给一个servlet来处理,如果servlet处理完成之后,希望将页面显示给用户,需要去调用页面,就可以使用转发

一个servlet在执行过程中,如果需要调用另外一个servlet,那么此时就可以使用转发。

转发----页面跳转相关的

要注意,转发前后使用的方法应该相同

package com.cskaoyan.request.forward;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @ClassName ${NAME}
 * @Description: TODO
 * @Author 远志 zhangsong@cskaoyan.onaliyun.com
 * @Date 2021/12/9 11:15
 * @Version V1.0
 **/
@WebServlet("/forward1")
public class ForwardServlet1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //访问forward1,需要在代码中去调用forward2,把2里面的数据显示出来
        System.out.println("forward1");
        //需要在forward1中去调用forward2
        //千万不要自己去new一个servlet,然后调用service
        //生命周期应该交由tomcat来统一管理
        //你去给tomcat发送一个指令,让tomcat去调用它
        //这行代码的作用是给tomcat发送一个指令,告诉tomcat去加载当前应用下的/forward2
        //tomcat就去加载forward2,如果它之前没有被访问过,首先实例化;如果访问过,直接调用service方法
        //记住唯一的特殊情况:tomcat的转发中/开头不要加应用名
        //看路径的解析执行主体是谁,如果是浏览器,则/应用名/资源路径,如果是服务器,则/资源路径
        request.getRequestDispatcher("/forward2").forward(request, response);
    }
}
ackage com.cskaoyan.request.forward;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @ClassName ${NAME}
 * @Description: TODO
 * @Author 远志 zhangsong@cskaoyan.onaliyun.com
 * @Date 2021/12/9 11:15
 * @Version V1.0
 **/
@WebServlet("/forward2")
public class ForwardServlet2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("forward2");
    }
}

request域

context域:一块内存空间,可以作为运行时共享数据的场所。

只要是同一个应用下的不同资源,拿到的都是同一个servletContext对象,那么就可以共享context域

request域:只要可以拿到同一个request对象,那么也可以共享request域

如果一个地址频繁刷新,每次都会创建新的request对象

要注意只有同一个request对象才能共享request域

主要体现在转发的过程中

只有转发的两个组件间可以共享数据

用法:

1.比如查询数据,先到servlet中执行查询数据库的逻辑,拿到数据之后,放入request域中,然后将数据共享给jsp(本质来说就是servlet, 页面、servlet)

htttp://localhost/app/productList

------> servlet-----DB query List—放入request域中,转发请求到jsp页面,在页面中进行渲染数据

目录
相关文章
|
1天前
|
存储 JavaScript 前端开发
JavaScript基础
本节讲解JavaScript基础核心知识:涵盖值类型与引用类型区别、typeof检测类型及局限性、===与==差异及应用场景、内置函数与对象、原型链五规则、属性查找机制、instanceof原理,以及this指向和箭头函数中this的绑定时机。重点突出类型判断、原型继承与this机制,助力深入理解JS面向对象机制。(238字)
|
2天前
|
安全 数据可视化 网络安全
安全无小事|阿里云先知众测,为企业筑牢防线
专为企业打造的漏洞信息收集平台
1300 2
|
3天前
|
云安全 人工智能
2025,阿里云安全的“年度报告”
拥抱AI时代,阿里云安全为你护航~
1447 2
|
10天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1406 7
|
11天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
1285 16
|
4天前
|
人工智能 前端开发 API
Google发布50页AI Agent白皮书,老金帮你提炼10个核心要点
老金分享Google最新AI Agent指南:让AI从“动嘴”到“动手”。Agent=大脑(模型)+手(工具)+协调系统,可自主完成任务。通过ReAct模式、多Agent协作与RAG等技术,实现真正自动化。入门推荐LangChain,文末附开源知识库链接。
496 118
|
1天前
|
人工智能 自然语言处理 API
n8n:流程自动化、智能化利器
流程自动化助你在重复的业务流程中节省时间,可通过自然语言直接创建工作流啦。
290 3
n8n:流程自动化、智能化利器
|
3天前
|
机器学习/深度学习 测试技术 数据中心
九坤量化开源IQuest-Coder-V1,代码大模型进入“流式”训练时代
2026年首日,九坤创始团队成立的至知创新研究院开源IQuest-Coder-V1系列代码大模型,涵盖7B至40B参数,支持128K上下文与GQA架构,提供Base、Instruct、Thinking及Loop版本。采用创新Code-Flow训练范式,模拟代码演化全过程,提升复杂任务推理能力,在SWE-Bench、LiveCodeBench等基准领先。全阶段checkpoint开放,支持本地部署与微调,助力研究与应用落地。
389 1
|
2天前
|
安全 API 开发者
手把手带你使用无影 AgentBay + AgentScope 完成一站式智能体开发部署
阿里云无影 AgentBay 作为一个面向 AI 智能体开发的云端 GUI 沙箱服务,已集成至阿里巴巴通义实验室开源的 AgentScope 框架,助力开发者快速构建安全、高效的智能体应用。
233 1

热门文章

最新文章