有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

utf 8 Java URL编码器保留原始消息的大小写,但使UTF8代码小写

我正在使用URLEncoder。编码(信息“UTF-8”);对字符串进行编码

问题在于,我需要最后一个字符串中的UTF-8代码为小写,同时保留原始消息的大小写

例如:

消息:{消息

所需输出:%1消息

URL编码器。编码(“{Message”,“UTF-8”);->;%5b消息

URL编码器。编码(信息“UTF-8”)。toLowerCase()->;%5B信息

有没有办法改变URLEncoder的行为

对于所有UTF-8字符和任意字符串长度,是否有一种简单的方法可以在事后将所有UTF-8代码转换为小写


共 (3) 个答案

  1. # 1 楼答案

    The problem is that I need the UTF-8 codes in the final string to be lower case, while maintaining the case of the original message.

    我认为您的意思是希望URL转义符中的十六进制数字用小写字母表示(这些不是“UTF-8代码”)。无论如何,这是一个糟糕的问题,因为URL编码规范(也称为“百分比编码”)明确规定百分比代码中的十六进制数字不区分大小写。只有在这些十六进制数字的情况下才有差异的2%编码URL是等效的,因此,处理它们的代码可能是一个持续的问题,只要它在使用中

    Is there a way to change the behavior of URLEncoder?

    The docs of ^{}非常简短。不需要太多的检查就可以看出,不,没有调节其行为这一方面的机制。您可以编写自己的实现(这并不难),或者您可以找到第三方编码器,但标准库的编码器将无法满足您的需求

    Is there an easy way to convert all the UTF-8 codes to lower case after the fact, for all UTF-8 characters and for arbitrary string length?

    这取决于你所说的“容易”是什么意思。原则上可以执行这样的转换,但是当您解析和更新编码的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) {
            StringBuffer sb = new StringBuffer();
            Matcher m = CODE_PATTERN.matcher(urlString);
    
            while (m.find()) {
                m.appendReplacement(sb, m.group().toLowerCase());
            }
            m.appendTail(sb);
    
            return sb.toString();
        }
    }
    
  2. # 2 楼答案

    我的解决方案是将URLEncoder源代码复制到一个新类中,并将hextr常量从“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
    
  3. # 3 楼答案

    这已经硬编码到URLEncoder中(我正在查看Oracle的JDK btw)。转换基本上是转换字符,并获取每个字符的十六进制值,然后减去'a' -'A'(字符值的大小写差异)之间的差异,以强制使用大写值

    if (Character.isLetter(ch)) {
        ch -= caseDiff;
    }
    

    我认为你能绕过这个问题的唯一方法是使用反射并将URLEncoder#caseDiff修改为0,因为这个变量是静态的final:

    static final int caseDiff = ('a' - 'A');
    

    通过这样做(考虑一下这个psudeo代码,你会想再看一遍):

    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();
    }
    

    我真的很好奇你这么做的意图,我想知道这是否真的是你想做的