自己动手写Web容器之TomJetty之五:包装请求参数

EXI编解码避坑指南:ISO15118-2协议中3条异常命令的差异分析 本文深度剖析了ISO15118-2协议测试中EXI编解码的典型问题,聚焦于ChargeParameterDiscoveryRes、CertificateInstallationReq和MeteringReceiptReq三条命令在不同工具间产生109字节差异的现象。通过对比EXICodec.jar、OpenEXI和Efficient XML的输出,揭示了差异根源于EXI报头处理机制与模式文件完整性,并提供了从现象确认、根因分析到解决方案的标准化排查流程,助力协议测试工程师确保编解码一致性与通信可靠性。 阅读详情

传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229

        前面我们实现了TomJetty响应无参请求静态页面的功能,但真实情况下,几乎所有请求都得携带参数。不能处理用户参数请求的Web服务器就好比温室里的花朵,始终上不了台面。所以本节我们将为TomJetty加入响应用户参数的功能。此外,前面我们使用的提交请求的方式都是GET方式,但在实际情况下,POST方式使用的更广泛,所以我们也将给TomJetty增加响应POST请求的能力。

1扩展RequestHeader类

1.1在RequestHeader类中新增parameter属性,用于标示请求头中客户请求的参数,并提供对应的getter/setter方法

private String parameter;

public String getParameter() {
    return parameter;
}

public void setParameter(String parameter) {
    this.parameter = parameter;
}

1.2在RequestHeaderParserImpl类的parse()方法中加入如下片段,用于解析在GET和POST两种提交方式下的请求头的参数部分,并将其保存到requestHeader对象中

String parameter = null;
try {
    if(method.equalsIgnoreCase("post")) {
        parameter = txt.substring(txt.lastIndexOf("\n") + 1, txt.length());
    } else if(method.equalsIgnoreCase("get")) {
        parameter = url.substring(url.indexOf("?") + 1, url.length());
        url = url.substring(0, url.indexOf("?"));
    }
} catch (Exception e) {
}

header.setParameter(parameter);

2自定义请求参数类

        创建一个Parameter类,采用键值对的方式存储请求携带的参数。如果直接使用HashMap数据结构进行存储,由于其底层的设计原则,将无法避免客户端浏览器重复提交的问题。

package cn.lynn.tomjetty;

public class Parameter {

    private String key;
    
    private String value;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((key == null) ? 0 : key.hashCode());
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final Parameter other = (Parameter) obj;
        if (key == null) {
            if (other.key != null)
                return false;
        } else if (!key.equals(other.key))
            return false;
        if (value == null) {
            if (other.value != null)
                return false;
        } else if (!value.equals(other.value))
            return false;
        return true;
    }
    
}

3封装请求对象

        前面我们讲过,为Java语言服务的Web容器,实际上装载的是Servlet(Java服务端应用程序)。打开Java EE帮助文档,检索Servlet关键字。可以看到Servlet实际上被设计成一个接口。其设计层次如下:


        它有三个实现子类,分别对应于不同的网络协议,这里我们只关注HttpServlet。此外,它还声明了五个方法,分别是:destroy()、getServletConfig()、getServletInfo()、init()、service(ServletRequest req, ServletResponse res),学过JSP的同学知道,service()方法才是Servlet容器响应请求的核心方法。看到这里,我们将Servlet相关HTTP协议的架构设计思想引入到TomJetty中。

3.1.新建一个Servlet接口,并声明一个service()方法

package cn.lynn.tomjetty;

public interface IServlet {

    public void service(Request req, Response res);

}

3.2新增一个IServlet接口的HTTP协议实现类HttpServletImpl,并提供doGet()方法和doPost()方法(方法体暂时为空)分别处理来自客户端浏览器的两种不同的提交方式

package cn.lynn.tomjetty;

public class HttpServletImpl implements IServlet {

    public void service(Request req, Response res) {
    }

    public void doGet(Request req, Response res) {
    }
    
    public void doPost(Request req, Response res) {
    }
}

        那么为什么要添加这两个方法?通过查看Java EE的HttpServlet的设计文档,我们知道HttpServlet也提供了这两个方法。当然提供的不止这两个,还有doDelete()、doPut()等,呵呵,想多了,它们不属于本系列关注的范畴^_^。



        我们发现service()方法中传入参数类型已经不是普通的Request和Response,Servlet对它们进行了封装。所以我们也照猫画虎学着做。

3.3新建一个Request类,用于封装HTTP请求头和请求参数。并提供对应的存取它们的方法以供外部调用

package cn.lynn.tomjetty;

import java.util.ArrayList;
import java.util.List;

public class Request {
    // 引入请求头
    private RequestHeader header;
    // 设置参数集合
    private List<Parameter> params = new ArrayList<Parameter>();
    // 设置请求参数
    public void setParameter(String param) {
        if(param == null || param.trim().equals("")) {
            return;
        }
        
        String[] result = param.split("&");
        
        for (int i = 0; i < result.length; i++) {
            Parameter parameter = new Parameter();
            parameter.setKey(result[i].split("=")[0]);
            parameter.setValue((result[i].split("=").length <= 1) ? "" : result[i].split("=")[1]);
            params.add(parameter);
        }
    }
    // 获取请求参数的值
    public String getParameterValue(String key) {
        String result = null;
        for(Parameter parameter : params) {
            if(parameter.getKey().equals(key)) {
                result =  parameter.getValue();
            }
        }
        return result;
    }

    public RequestHeader getHeader() {
        return header;
    }

    public void setHeader(RequestHeader header) {
        this.header = header;
    }
}

3.4在TomJetty类的run()方法中加入如下片段,将请求头和请求参数存放到Request对象中进行统一管理

// 封装请求头
Request request = new Request();
request.setParameter(header.getParameter());
request.setHeader(header);

4响应请求参数效果展示

4.1GET方式提交


        在IE浏览器输入上述地址后回车,控制台打印如下:

RequestHeader [
GET /index.htm HTTP/1.1
Accept: */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; KB974488)
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:9527
Connection: Keep-Alive
Cookie: null
parameter: username=lynnli1229&password=123456
]

4.2POST方式提交

        新建一个input.htm文件,在其<body>标签内编写一个表单用于POST提交用户信息。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="http://127.0.0.1:9527/index.htm" name="form" id="form" method="post">
    用户名:<input name="username" type="text"></br>
    密    码:<input name="password" type="password"></br>
        <input name="submit" value="提交" type="submit">
        <input name="reset" value="重置" type="reset">
    </form>
</body>
</html>

        在IE浏览器输入上述地址后回车,接着填写表单项,点击提交按钮,页面会导航到index.htm,控制台打印如下:

RequestHeader [
GET /input.htm HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/QVOD, application/QVOD, */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; KB974488)
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:9527
Connection: Keep-Alive
Cookie: null
parameter: /input.htm
]
RequestHeader [
POST /index.htm HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/QVOD, application/QVOD, */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; KB974488)
Accept-Encoding: gzip, deflate
Host: 127.0.0.1:9527
Connection: Keep-Alive
Cookie: null
parameter: username=lynnli1229&password=123456&submit=%E6%8F%90%E4%BA%A4
]

        至此,TomJetty服务器已经能够在POST和GET两种请求提交方式下,都可以为携带参数的静态页面请求提供服务。然而只能处理静态页面请求的服务器还是远远不够的,毕竟现阶段动态网页才是主流。所以下一节我们将赋予TomJetty服务器处理动态网页的能力。

Cesium 实现动态加载气象数据:渲染成动态雨雪/云层效果(源码 + 原理) 本文介绍了在Cesium中实现动态天气效果的技术方案。核心思路是通过时间轴驱动多层数据动态切换,包括:1)时间维度处理,按序列加载不同气象图层;2)空间维度处理,将气象数据切分为瓦片;3)效果层实现,制作风场、降水等动态可视化效果。文章详细讲解了后端数据预处理(生成瓦片和风场JSON)、前端实现(双层雷达瓦片交替渐变、风场粒子系统)的具体方法,并提供了完整的代码示例。此外还探讨了雨雪粒子、云层效果等增强功能,以及工程化建议,为构建科学准确的动态天气可视化系统提供了实用解决方案。 阅读详情

相关推荐

robot framework循环读取excel表操作

robot framework循环读取excel表操作 1、安装excellibrary,注意python3.7版本,需安装:robotframework-excel,robotframework-excellibrary-xwfintech 注意:网上有很多excel处理的,都是基于python2.7的,还有一些对python3以上都是修改包的方式,其实都不需要,在pip官网上有python3以上的excellibrary,名称是robotframework-excellib 2.0.0,但是该包关键字不

余墨的博客 1319

嵌入式jetty相关知识总结

1嵌入式jetty简介 在介绍嵌入式jetty之前,首先介绍一下jetty。 Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和Web连接。

李昊的专栏 3866

从零开始:用这些公开数据集搞定电力AI项目(含鸟巢、绝缘子、负荷预测等33个实战资源)

本文系统梳理了电力AI领域33个精选公开数据集,涵盖目标检测、负荷预测等关键场景,如鸟巢检测、绝缘子缺陷识别等。通过实战案例解析数据预处理、模型选型及性能优化策略,帮助工程师快速构建端到端解决方案,解决电力AI项目中的数据获取与处理难题。

weixin_42522552的博客 216

自己动手写Web容器之TomJetty之三:掀起请求盖头来

传送门☞轮子的专栏☞转载请注明☞http://blog.youkuaiyun.com/leverage_1229 前面我们对于实现TomJetty做了一些知识铺垫和复习,息知了HTTP请求的头部的组成元素。目前的TomJetty服务器已经能够成功启动,可是请求一旦过来却又看不懂^_^。所以本文就来解析HTTP请求头,剖析它的各部分。让TomJetty服务器能够明白它的意图。 ...

weixin_30262255的博客 116

虚拟机Ubuntu连接USRP

笔记本通过网线连接USRP。

xiaozir的博客 2307

15、z/OS 优化配置与迁移实践

本文详细探讨了z/OS环境的优化配置与迁移实践,涵盖DASD存储库管理、用户目录更新、环境更新意义以及不同场景下的迁移案例。通过单笔记本系统和服务器级机器的实例,展示了迁移流程和关键要点,包括DASD文件创建、设备映射更新、系统重启初始化以及数据备份等步骤。文章还总结了迁移过程中的注意事项,并展望了未来z/OS优化的发展趋势,为z/OS系统的稳定运行和高效管理提供了实用指导。

zzz56的博客 129

深入Jetty源码之Servlet框架及实现(ServletRequest、ServletResponse)

概述 Servlet是Server Applet的缩写,即在服务器端运行的小程序,而Servlet框架则是对HTTP服务器(Servlet Container)和用户小程序中间层的标准化和抽象。这一层抽象隔离了HTTP服务器的实现细节,而Servlet规范定义了各个类的行为,从而保证了这些“服务器端运行的小程序”对服务器实现的无关性(即提升了其可移植性)...

weixin_34138255的博客 572

STM32+ESP8266+MQTT协议连接阿里云物联网平台

一、环境介绍 单片机采用:STM32F103C8T6 上网方式:采用ESP8266,也可以使用其他设备代替,只要支持TCP协议即可。比如:GSM模块、有线网卡等。 开发软件:keil5 二、实现功能 通过阿里云物联网服务器实现设备数据远程上传、下发,实现数据交互。 在当前使用的开发板上有4盏LED灯、一个蜂鸣器、4个按键。 三、阿里云物联网服务器创建步骤 说明:如果没有账号的话,先点击网页右上角,注册一个账号,并完成实名认证再继续下一步。 产品名称根据自己情况填...

6万+

Jersey框架:封装基于Jetty的通用服务器

1.需求场景 依赖于Jetty容器封装一个Jersey微服务的启动类,在微服务入口中通过简单的调用即可实现微服务启动。主要需求如下: 可以指定服务启动端口 可以指定服务的应用域路径 可以指定要注册到Jersey容器的资源包 可以指定要注册到Jersey容器的资源类 2.设计思路 在通用封装类中维护一个Jetty的Server实例,代表真正的服务器 默认注册res、filter和excepti...

机器熊的技术大杂烩 612

别再无脑调打码平台了!聊聊 ddddocr 在爬虫验证码识别中的真实边界

ddddocr是国产开源社区的优秀成果,它大幅降低了验证码识别的入门门槛。工具的自由不等于工程的自由。真正的能力不在于“会不会调库”,而在于能否准确判断工具的适用边界、构建鲁棒的容错机制、并在成本与效果之间做出理性权衡。下次当你准备在爬虫中加入验证码识别时,不妨先问自己:这个站点的验证码类型是否在ddddocr的能力圈内?我的预处理是否针对该站点做过专项调试?我的失败重试和监控机制是否完备?如果三个问题都能肯定回答,那么ddddocr就是你的利器;如果有任何一个犹豫,请先补齐短板再上路。评论区交流:你用。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1281

2026华为OD机试(JavaScript)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,JavaScript实现。

MISAYAONE的博客 8万+

自己动手写Web容器之TomJetty之一:服务内功经脉

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 2.开启服务器 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面起步 传送门 ☞ 5.包装请求参数 传送门 ☞ 6.动态页面引入         Jetty 是一个开源的servlet容器,它为基于Java的web内容,

leverli的专栏 4481

药物对接仿真软件:HADDOCK_(16).实践项目:抗体-抗原对接案例

定义分子结构文件。

kkchenjj的博客 579

自己动手写Web容器之TomJetty之四:静态页面起步

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 1.服务内功经脉 传送门 ☞ 2.开启服务器 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 5.包装请求参数 传送门 ☞ 6.动态页面引入         上一节我们实现了将HTTP请求头的内容解析后打印到控制台上,让HTTP请求头的各个

leverli的专栏 3435

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

自己动手写Web容器之TomJetty之六:动态页面引入

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 系统架构设计 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ GoF23种设计模式 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 1.服

leverli的专栏 6430

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

自己动手写Web容器之TomJetty之二:开启服务器

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 1.服务内功经脉 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面启步 传送门 ☞ 5.包装请求参数 传送门 ☞ 6.动态页面引入         上一节我们对于实现TomJetty服务器做了一些与Web有关的知识铺垫和回顾。那

leverli的专栏 3344

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

[置顶] 自己动手写Web容器之TomJetty之六:动态页面引入

传送门 ☞ Android兵器谱 ☞ 转载请注明 ☞ http://blog.youkuaiyun.com/leverage_1229 传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 2.让服务动起来 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面起步 传送门 ☞ 5.包装请求参数         在上一节,我们已经完成了TomJetty服务器处理静态页面请求的功能。但是只能处理...

weixin_34242331的博客 110

[置顶] 野生Web容器之TomJetty之掀起你的盖头来

传送门:上一节         上文我们对于实现这个野生Web容器做了一些知识铺垫和复习,息知了HTTP请求的头部的组成元素,本文我们主要讲解如何在代码中去解析它的各个部分,掀起盖头来,给哥笑一个^_^。在这之前,我们需要建立服务器,把框架搭建起来。 一、服务器建立 1.新建一个名为TomJetty的Java工程。 2.在工程src目录下新建一个tomjetty.config文件,用于提...

weixin_33798152的博客 168

[置顶] 野生Web容器之TomJetty之内功经脉

        Jetty 是一个开源的servlet容器,它为基于Java的web内容,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。Tomcat 是一个免费的开放源代码的Web 应用服务器,属于轻量级...

weixin_34138521的博客 97

[置顶] “非主流”Web容器之TomJetty之让服务动起来

  传送门 ☞ 1.Web服务内功经脉 传送门 ☞ 3.掀起请求盖头来 传送门 ☞ 4.静态页面启程         上一节我们对于实现TomJetty服务器做了一些与Web有关的知识铺垫和回顾。那么从本节正式开始实现TomJetty服务器的“山寨”之旅。要想实现一个服务器,第一步要把服务器建立起来,并且能够正常运行,才能等待来自客户端的请求。考虑到这一点,我们本节就来处理TomJet...

weixin_34235457的博客 104
上一篇: Android玉石短剑之GridView之精挑细选
下一篇: 某大型银行深化系统之一:平台技术
innovation
博客等级 码龄14年 251粉丝 136原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值