Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有一个通用的Java库来处理字符串集合的URL编码/解码?_Java_Urlencode_Urldecode - Fatal编程技术网

是否有一个通用的Java库来处理字符串集合的URL编码/解码?

是否有一个通用的Java库来处理字符串集合的URL编码/解码?,java,urlencode,urldecode,Java,Urlencode,Urldecode,我经常需要对大量的字符串集合或数组进行url编码或解码。除了遍历它们并使用静态urldecker.decode(字符串,“UTF-8”),还有没有库可以使这种类型的操作更高效 一位同事坚持认为,使用静态方法就地解码字符串不是线程安全的。为什么会这样?Apache有一个可用于编码和解码的 如果静态方法只对局部变量或最终初始化的变量起作用,那么它是完全线程安全的 由于参数位于堆栈上,并且是完全线程安全的,所以最终常量是不可变的,因此不能更改 以下代码是完全线程安全的: public static S

我经常需要对大量的字符串集合或数组进行url编码或解码。除了遍历它们并使用静态urldecker.decode(字符串,“UTF-8”),还有没有库可以使这种类型的操作更高效

一位同事坚持认为,使用静态方法就地解码字符串不是线程安全的。为什么会这样?

Apache有一个可用于编码和解码的

如果静态方法只对局部变量或最终初始化的变量起作用,那么它是完全线程安全的

由于参数位于堆栈上,并且是完全线程安全的,所以最终常量是不可变的,因此不能更改

以下代码是完全线程安全的:

public static String encodeMyValue(String value){
  // do encoding here
}

如果最终变量是可变的,这意味着您不能重新分配它,但可以更改其内部表示(属性),则应小心。

对于静态函数,线程安全实际上从来都不是必需的(或者是设计失败)。尤其是,如果用户甚至不访问类中的静态变量


我建议使用您以前使用的函数,并在集合中迭代,JDK URLDecover没有有效地实现。最值得注意的是,它在内部依赖于StringBuffer(在URLDecover的情况下不必要地引入同步)。ApacheCommons提供了,但也有报道称它在性能方面存在类似的问题,但我还没有证实在最新版本中仍然存在这种情况

不久前写了一篇关于URLDecover的问题和性能的帖子。他记录了一些bug报告,最后写了一个完整的替代品。正因为如此,我将在这里引用一些关键摘录,但您应该在这里真正阅读完整的源文章:

精选语录:

Java在中提供了此功能的默认实现 java.net.URLEncoder和java.net.URLEncoder。不幸的是,事实并非如此 由于API的编写方式以及 实施过程中的细节。若干与性能有关的问题 已经在sun.com上提交了与URLEncoder相关的bug

还有一种选择:org.apache.commons.codec.net.URLCodec from apachecommons编解码器。(Commons编解码器还提供了一个有用的 Base64编码的实现。)不幸的是,Commons的URLCodec 与Java的URLEncoder/URLDecoder存在一些相同的问题

对JDK和Commons的建议:

当构造任何“缓冲区”类时,例如。 ByteArrayOutputStream、CharArrayWriter、StringBuilder或 StringBuffer,估计并传入估计容量。JDK的 URLEncoder当前为其StringBuffer执行此操作,但应执行此操作 这也是因为它的CharacterWriter实例。通用的URL编解码器 应该为其ByteArrayOutputStream实例执行此操作。如果课程是 默认缓冲区大小太小,可能必须通过复制来调整大小 进入新的、更大的缓冲区——这并不是一个“便宜”的操作。如果 类的默认缓冲区大小太大,内存可能不足 不必要的浪费

这两种实现都依赖于字符集,但只接受它们 作为字符串名。Charset为用户提供了一个简单而小的缓存 名称查找-仅存储使用的最后2个字符集。这不应该 两者都应接受其他对象的字符集实例 互操作性也是原因之一

这两种实现只处理固定大小的输入和输出。这个 JDK的URLEncoder只适用于字符串实例。Commons的URL编解码器 也基于字符串,但也适用于byte[]数组。这是一个 本质上阻止有效处理的设计级约束 指较大或可变长度的输入。相反,“流支持” 接口,如CharSequence、Appendable和java.nio的缓冲区 应支持ByteBuffer和CharBuffer的实现

请注意,com.ziesemer.utils.urlCodec的速度是JDK的3倍多 URLEncoder,速度是JDK URLDecoder的1.5倍以上。(JDK的 URLDecoder比URLEncoder快,所以没有那么多 (还有改进的余地。)

我认为你的同事错误地认为URLDecode不是线程安全的。其他答案在这里详细解释

编辑[2012-07-03]-根据OP随后发布的评论

不确定你是否在寻找更多的想法?如果要将列表作为原子集合进行操作,则必须同步对列表的所有访问,包括方法之外的引用,这是正确的。但是,如果您同意返回的列表内容可能与原始列表不同,那么对可能被其他线程修改的集合中的“批”字符串进行操作的蛮力方法可能如下所示:

/**
 * @param origList will be copied by this method so that origList can continue
 *                 to be read/write by other threads. 
 * @return list containing  decoded strings for each entry that was 
           in origList at time of copy.
 */
public List<String> decodeListOfStringSafely(List<String> origList)
        throws UnsupportedEncodingException {
    List<String> snapshotList = new ArrayList<String>(origList);
    List<String> newList  = new ArrayList<String>(); 

    for (String urlStr : snapshotList) {
      String decodedUrlStr  = URLDecoder.decode(urlStr, "UTF8");
          newList.add(decodedUrlStr);
    }

    return newList;
}
/**
*@param origList将被此方法复制,以便origList可以继续
*被其他线程读/写。
*@return list,其中包含每个被删除条目的解码字符串
在复印时使用原版英语。
*/
公共列表DecodeListofStringSafety(列表或英文)
抛出不支持的DencodingException{
列表快照列表=新的ArrayList(origList);
List newList=newarraylist();
用于(字符串urlStr:snapshotList){
字符串decodedUrlStr=urldecover.decode(urlStr,“UTF8”);
newList.add(decodedUrlStr);
}
返回newList;
}

如果这没有帮助,那么我仍然不确定你在追求什么,你最好能提出一个新的、更简洁的问题。如果这就是你要问的问题,那么要小心,因为这个断章取义的例子在很多方面都不是一个好主意。

基本上没有神奇的线程安全应用程序