java querystring_搞定queryString

java querystring_搞定queryStringquerystring 字面上的意思就是查询字符串 一般是对 http 请求所带的数据进行解析 querystring 模块只提供 4 个方法 querystring parsequeryst stringifyque escapequerys unescape 这 4 个方法是相对应的 首先 使用 querystring 模块之前 需要 require 进来 constqueryst

querystring字面上的意思就是查询字符串,一般是对http请求所带的数据进行解析。querystring模块只提供4个方法:

querystring.parse

querystring.stringify

querystring.escape

querystring.unescape

这4个方法是相对应的。

首先,使用querystring模块之前,需要require进来:

const querystring = require(“querystring”);

其次,就可以使用模块下的方法了:

1 querystring.parse(str,separator,eq,options)

parse这个方法是将一个字符串反序列化为一个对象。

参数:

str指需要反序列化的字符串;

separator(可省)指用于分割str这个字符串的字符或字符串,默认值为”&”;

eq(可省)指用于划分键和值的字符或字符串,默认值为”=”;

options(可省)该参数是一个对象,里面可设置maxKeys和decodeURIComponent这两个属性:

maxKeys:传入一个number类型,指定解析键值对的最大值,默认值为1000,如果设置为0时,则取消解析的数量限制;

decodeURIComponent:传入一个function,用于对含有%的字符串进行解码,默认值为querystring.unescape。在官方API的例子中,使用gbkDecodeURIComponent这个方法会报错,显示gbkDecodeURIComponent is no defined,这是因为在使用这个gbkDecodeURIComponent这个方法之前需要先进行定义。在API中也写了Assuming gbkDecodeURIComponent function already exists…这句话的意思是”假设这个gbkDecodeURIComponent方法已经存在”。

例子1,querystring.parse

1 querystring.parse(“name=whitemu&sex=man&sex=women”);2 /*3 return:

4 { name: ‘whitemu’, sex: [ ‘man’, ‘women’ ] }

5*/

6 querystring.parse(“name=whitemu#sex=man#sex=women”,”#”,null,{maxKeys:2});7 /*8 return:

9 { name: ‘whitemu’, sex: ‘man’ }

10*/

2 querystring.stringify(obj,separator,eq,options)

stringify这个方法是将一个对象序列化成一个字符串,与querystring.parse相对。

参数:

obj指需要序列化的对象

separator(可省)用于连接键值对的字符或字符串,默认值为”&”;

eq(可省)用于连接键和值的字符或字符串,默认值为”=”;

options(可省)传入一个对象,该对象可设置encodeURIComponent这个属性:

encodeURIComponent:值的类型为function,可以将一个不安全的url字符串转换成百分比的形式,默认值为querystring.escape()。

例子2,querystring.stringify

querystring.stringify({name: ‘whitemu’, sex: [ ‘man’, ‘women’] });/*return:

‘name=whitemu&sex=man&sex=women’*/querystring.stringify({name:’whitemu’, sex: [ ‘man’, ‘women’ ] },”*”,”$”);/*return:

‘name$whitemu*sex$man*sex$women’*/

3 querystring.escape(str)

escape可使传入的字符串进行编码

例子3,querystring.escape

querystring.escape(“name=慕白”);/*return:

‘name%3D%E6%85%95%E7%99%BD’*/

4 querystring.unescape(str)

unescape方法可将含有%的字符串进行解码

例子4,querystring.unescape

querystring.unescape(‘name%3D%E6%85%95%E7%99%BD’);/*return:

‘name=慕白’*/

小结:

querystring这个模块相对的还是比较简单,仅有4个方法。

querystring.stringify序列化;

querystring.parse反序列化;

querystring.escape编码;

querystring.unescape解码;

进阶版

可以写一个函数,专门用于做转换

private object ConvertParameter(string name, object defaultValue, bool isRequired)

我们甚至还可以把它抽象出来一个方法。

提取抽象方法

用Attribute和反射的思想,首先给变量设置HttpQueryString的属性,绑定上相应的QueryString,然后由Page基类来读取相应的QueryString信息。

属性这么写(HttpQueryStringAttribute.cs):

[AttributeUsage(AttributeTargets.Field)]public sealed classHttpQueryStringAttribute : Attribute {privatestring _name;privateobject _defaultValue;privatebool _isRequired;publicHttpQueryStringAttribute(string name) {

_name=name;

_defaultValue= null;

_isRequired= true;

}publicHttpQueryStringAttribute(string name, object defaultValue) {

_name=name;

_defaultValue=defaultValue;

_isRequired= false;

}publicstring Name {

get {return_name; }

}publicobject DefaultValue {

get {return_defaultValue; }

}publicbool IsRequired

{

get {return_isRequired; }

}

}

页面基类是这样的(PageBase.cs):

public classPageBase : Page

{protected override voidOnLoad(System.EventArgs e) {

ParameterInitialize();

base.OnLoad(e);

}private voidParameterInitialize() {

Type type= this.GetType();

FieldInfo[] fields=type.GetFields();

foreach (FieldInfo field in fields)

{

HttpQueryStringAttribute attribute=(HttpQueryStringAttribute)Attribute.GetCustomAttribute(field, typeof(HttpQueryStringAttribute));if (attribute != null)

{

SetField(field, attribute);

}

}

}private voidSetField(FieldInfo field, HttpQueryStringAttribute attribute)

{if(attribute.IsRequired)

{if (Request.QueryString[attribute.Name] != null)

{

SetFieldValue(field,this, attribute.Name, field.FieldType);

}else{throw new Exception(string.Format(“Query string /”{0}/” is required”, attribute.Name), newNullReferenceException());

}

}else{if (attribute.DefaultValue == null || field.FieldType ==attribute.DefaultValue.GetType())

{if (Request.QueryString[attribute.Name] == null || Request.QueryString[attribute.Name] ==string.Empty)

{

field.SetValue(this, attribute.DefaultValue);

}else{

SetFieldValue(field,this, attribute.Name, field.FieldType);

}

}else{throw new Exception(string.Format(“Invalid default value of query string /”{0}/”({1})”, attribute.Name, field.Name), newNullReferenceException());

}

}

}private voidSetFieldValue(FieldInfo field, object obj, string name, Type conversionType) {try{

field.SetValue(obj, Convert.ChangeType(Request.QueryString[name], conversionType));

}catch(Exception ex)

{throw new Exception(string.Format(“The given value of query string /”{0}/” can not be convert to {1}”, name, conversionType), ex);

}

}

}

在页面里,这样写就OK了(Default.aspx.cs):

public partial class_Default : PageBase

{

[HttpQueryString(“Name”, “Anonymous”)]publicstring name;

[HttpQueryString(“UserId”)]public intuserId;protected voidPage_Load(object sender, EventArgs e)

{

}

}

讨论

根据定义的变量的数据类型自动转换对应的QueryString,可以省去以后在页面里处理Query String的代码。

反过来想,QueryString 的处理没必要上升到反射的高度,复杂的实现也许会丧失一定的灵活性。比如我某个值忽然要改为从 Form 里面得到呢?从 Session 得到呢?这时候就可以比较出哪种做法更适合敏捷的适应需求。

页面里的 QueryString 的处理,之所以大家都很痛恨手工写编码,无非是因为这么几点:

需要判断是否 == null 才敢用 .ToString(), 很不爽。稍微不注意,就会抛出异常导致页面错误。

整形,double 等值类型从 QueryString 里面获取的时候,不知道是否为合法的数值,因此 Parse 的时候总是要写重复的处理异常的代码。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/205265.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午6:25
下一篇 2026年3月19日 下午6:25


相关推荐

  • 书单(含资源链接,快撸!)

    书单(含资源链接,快撸!)撸资源python开发笨办法”学Python(第3版)Python.编写高质量Python代码的59个有效方法提取码:3vk4编写高质量代码改善python程序的91个建议利用Pytho

    2022年8月4日
    12
  • PhpStorm本地断点调试

    PhpStorm本地断点调试1、断点调试php环境搭建2、开始你的断点调试3、断点调试的一些简单操作

    2022年5月21日
    50
  • 手机的屏幕分辨率_手机屏幕分辨率尺寸

    手机的屏幕分辨率_手机屏幕分辨率尺寸  什么是分辨率?说白了,分辫率高,屏幕显示就更清晰、更细腻。分辨率不高,屏幕显示就会有颗粒感,粗糙感。一句话:分辨率是屏幕显示清晰度的一个指标。现在手机常用的分辫率有:128*160、176*220、240*320。128*160多用在低档的手机。中档的手机一般分辨率为176*220。中高档手机分辨率多为:240*320。夏普现在有一款手机分辨率达到了480*640。比电脑显示屏还清晰

    2022年8月13日
    13
  • OpenClaw 接入 Home Assistant:智能家居控制尝试

    OpenClaw 接入 Home Assistant:智能家居控制尝试

    2026年3月13日
    3
  • 可重入锁详解(什么是可重入)

    可重入锁详解(什么是可重入)可重入锁详解概述什么是“可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。例如packagecom.test.reen;//演示可重入锁是什么意思,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的//可重入降低了编程复杂性publicclassWhatReentrant{ publicsta…

    2022年4月19日
    50
  • 线程池实现原理_最通俗易懂的解读比特币相关原理

    线程池实现原理_最通俗易懂的解读比特币相关原理本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。一、早期通过JDBC方式操作数据库我们先来看早期使用JDBC的方式操作数据库的过程,这里以mysql数据库为例讲解JDBC操作数据库原理:一般来说,java应用程序访问数据库的过程是:   ①装载数据库驱动程序;   ②通过jdbc…

    2025年12月4日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号