我正在使用URLEncoder.encode(消息,“UTF-8”);编码一个字符串。
问题是我需要将最终字符串中的UTF-8代码设置为小写,同时保持原始消息的大小写。
例:
消息:{消息
期望输出:%5bMessage
URLEncoder.encode(“{Message”,“UTF-8”); - >%5BMessage
URLEncoder.encode(message,“UTF-8”)。toLowerCase(); - >%5bmessage
有没有办法改变URLEncoder的行为?
要么
对于所有UTF-8字符和任意字符串长度,是否有一种简单的方法可以将所有UTF-8代码转换为小写字母?
这是硬编码到URLEncoder(我正在看Oracle的JDK顺便说一句)。转换基本上转换您的角色,并获取每个角色的十六进制值,然后减去'a' -'A'
(char值中的大写差异小写)之间的差异,以强制使用大写值。
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
我认为你可以解决这个问题的唯一方法是使用反射并将URLEncoder#caseDiff
修改为0,因为这个变量是静态最终的:
static final int caseDiff = ('a' - 'A');
通过做类似的事情(考虑这个伪代码。你会想要第二次传递它):
try {
Field declaredField = URLEncoder.class.getDeclaredField("caseDiff");
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(declaredField, declaredField.getModifiers() & ~Modifier.FINAL);
declaredField.setAccessible(true);
declaredField.setInt(null, 0);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e1) {
e1.printStackTrace();
}
我真的很好奇你打算这样做,我想知道这是不是你想要做的。
问题是我需要将最终字符串中的UTF-8代码设置为小写,同时保持原始消息的大小写。
我认为你的意思是你希望URL转义中的十六进制数字用小写字母表示(这些不是“UTF-8代码”)。无论如何,这是一个令人讨厌的问题,因为URL编码(a.k.a。“百分比编码”)的规范明确指出百分比代码中的十六进制数字不区分大小写。仅在这些十六进制数字的情况下不同的两个百分比编码的URL是等效的,因此只要它在使用中,否则处理它们的代码可能是连续的问题。
有没有办法改变URLEncoder的行为?
The docs of java.net.URLEncoder
非常简短。不需要太多的检查就可以看到没有,没有机制来调整其行为的这个方面。您可以编写自己的实现(并不难),或者您可能会找到第三方编码器,但标准库的编码器将无法满足您的要求。
对于所有UTF-8字符和任意字符串长度,是否有一种简单的方法可以将所有UTF-8代码转换为小写字母?
这取决于你所说的“简单”。原则上可以执行这样的转换,但是当您解析和更新编码的URL时,您花费的工作量至少是在您希望的方式执行编码所花费的两倍。第一名。
但如果你真的想这样做,那么你可能会使用这样的东西:
import java.util.regex.*;
public class URLRecoder {
private final static Pattern CODE_PATTERN = Pattern.compile("%[0-9A-Fa-f]{2}");
/**
* Recodes a URL-encoded string to ensure that all hex digits in the
* percent codes that are not decimal digits are expressed in lowercase.
*/
public String recode(String urlString) {
StringBuilder sb = new StringBuffer();
Matcher m = CODER_PATTERN.matcher(urlString);
while (m.find()) {
m.appendReplacement(sb, m.group().toLowerCase());
}
m.appendTail(sb);
return sb.toString();
}
}
我的解决方案是将URLEncoder源复制到一个新类中,并将hexStr常量从“0123456789ABCDEF”更改为“0123456789abcdef”。
由于可能的许可问题,不打算在此处发布代码:
/*===========================================================================
* Licensed Materials - Property of IBM
* "Restricted Materials of IBM"
*
* IBM SDK, Java(tm) Technology Edition, v8
* (C) Copyright IBM Corp. 1995, 2013. All Rights Reserved
*
* US Government Users Restricted Rights - Use, duplication or disclosure
* restricted by GSA ADP Schedule Contract with IBM Corp.
*===========================================================================
*/
/*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.`
源版本:
* @version 1.31, 11/17/05