2 qq 31520675 qq_31520675 于 2017.01.13 12:55 提问

servlet接口中编码问题,求大神进来解决一下

图片说明我在servlet中对一串字符串进行加密,但是编码老是乱码,然后我进行了UTF-8处理图片说明就是这种,但是问题处理的不全面,出现的问题是经常有个别字符乱码图片说明求哪位大神帮忙解决一下

9个回答

strongerzhi
strongerzhi   2017.01.13 13:13
已采纳

在传输时对参数进行URL编码或者使用加密方式操作

strongerzhi
strongerzhi 你replaceAll("\0")去掉试了吗?这个很可能造成你现在的问题,你先试试
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 怎么解决啊,快烦死了
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 我觉得就是你分隔的问题,程序找错分隔的地方了
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 但是为什么有的字就没问题呢
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 现在很明显了,加密的时候把&一起加密进去了
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 我这个只是去掉可能带有的其他字符
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 那该替换成什么好呢
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 你为何要将'\0'替换成"",没什么道理呀!
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 我在下面添加了postFormLinkReport方法得代码,这主要是讲map处理成&连接的字符串
11 个月之前 回复
strongerzhi
strongerzhi 回复奔跑的小鱼儿: 其实是跟编码字节相关的,加密解密走的就是字节,而字符串一般以\0结尾,如果在加密解密过程中没有很好的处理分隔的话,就会出现乱码
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 你的问题,目前来看就是最后一个字在加密的时候(postFormLinkReport这里的处理)已经有了问题,只是处在最后一个字上,那么,要么你从根本上去解决这个问题,去查一下postFormLinkReport,要么你就规避这个问题,最后一个字不要出现汉字,应该也可以解决
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: 好逗的问题啊,是不是拼音以z开头的都出现乱码了
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 但是这样我试一下,发现当我手动将payeeName传过来的值改成“在不在”,那么会出现最后一个字乱码,如果我写成“在不在啊”则是正确的,这种问题怎么处理
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 我处理属性值时这样payeeName=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 还有一个方法你可以试一下,在中文后面加一个\0或者空格来处理一下,看看还会不会乱码
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: postFormLinkReport另一个接口如果也是servlet的话,你这里Post的时候完全可以做Url加密处理中文,如果不能,最好协调一下,URL中有中文的一定要做编码处理
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 您可以看一我下面贴的代码,我还要吧加密过得报文发到另一个接口,如果用URLencode内边是会直接给我返回报文解析失败
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 这个需要依赖于你的加密解密方法,你可以先将中文用base64或者urlencode等方法转成英文再处理
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 大神你说出了问题的情况啊,怎么处理也说一下啊
11 个月之前 回复
qq_31520675
qq_31520675 回复qq_31520675: 这样的话该怎么出理
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 请问这样该怎么出路
11 个月之前 回复
qq_31520675
qq_31520675 回复Kolamu: 对“样”也会出现乱码
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 你看下“样”结尾是不是也会出乱码
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675:跟后面的参数分隔符&连一起处理了
11 个月之前 回复
strongerzhi
strongerzhi 回复qq_31520675: 你这个是末尾是乱码还是只有末尾是在同音字的时候是乱码,如果末尾都是乱码的话,末尾应该缺少'\0'符
11 个月之前 回复
qq_31520675
qq_31520675 加密之后我再解开就是乱码
11 个月之前 回复
qq_31520675
qq_31520675 这是针对上一个字符串进行加密
11 个月之前 回复
qq_31520675
qq_31520675 我没有进行传输,srt2 = EncryDecryUtils.encryptFromDESBase64(DSEKey.trim(), dataStr2.trim());
11 个月之前 回复
u011606457
u011606457   2017.01.13 13:10

像是解密结果少了尾部的几个字节导致的,检查一下你的加解密算法

qq_31520675
qq_31520675 尾部没有少字节,而且只要字符串里没有和“在”同音的字就不会出现乱码,
11 个月之前 回复
welan123123
welan123123   2017.01.13 13:27

utf-8处理语句换一下
String datastr4 = new String(datastr3.getBytes("ISO-8859-1"), "utf-8");

qq_31520675
qq_31520675 回复奔跑的小鱼儿: 下发我贴上了这一块完整的代码
11 个月之前 回复
qq_31520675
qq_31520675 回复奔跑的小鱼儿: 没有用,基本都是问号或者乱码
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: getBytes("ISO-8859-1")里面的
11 个月之前 回复
qq_31520675
qq_31520675 括号内还是括号外
11 个月之前 回复
qq_31520675
qq_31520675 回复奔跑的小鱼儿: 换GBK是换哪部分
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: ISO-8859-1换成GBK和utf-8也试试
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: 反过来试试,.getBytes("UTF-8"),"ISO8859-1"),还不行就把代码贴全了
11 个月之前 回复
qq_31520675
qq_31520675 不行,换了之后直接全程问号了payeeCardNo=6217991000019408660&payeeName=???
11 个月之前 回复
qq_31520675
qq_31520675   2017.01.13 14:01
                    Map<String,String> map = new HashMap<String, String>();
                    map.put("mhtOrderNo",mhtOrderNo);
                    map.put("mhtReqTime",mhtReqTime);
                    map.put("payeeAccType",payeeAccType);
                    map.put("payeeName","祝在哪");
                    map.put("payeeCardNo",payeeCardNo);
                    map.put("mhtOrderAmt",mhtOrderAmt);
                    map.put("agentPayMemo",agentPayMemo);
                    map.put("payeeCardUnionNo",payeeCardUnionNo);
                    srt1 = this.base("appId=" +  Config.appId);
                    map = MapUtils.mapRemoveNull(map);
                    String dataStr = FormDateReportConvertor.postFormLinkReport(map);
                    //String datastr4 = new String(datastr3.getBytes("ISO-8859-1"), "utf-8");
                    String dataStr2=new String(dataStr.getBytes("utf-8"), "GBK");
                    srt2 = EncryDecryUtils.encryptFromDESBase64(DSEKey.trim(), dataStr2.trim());
                    srt3 = this.MD5Message(dataStr, MD5Key);
                    srt3 = this.base(srt3);
                    message1.append(srt1);  
                    message1.append("|");
                    message1.append(srt2); //拼接返回报文
                    message1.append("|");
                    message1.append(srt3);
                    return_mess.append(message1.toString());
                    Report=return_mess.toString().trim();
                    xml = HttpPost.http("https://dby.ipaynow.cn/agentpay/agentPay",Report);
qq_31520675
qq_31520675 回复奔跑的小鱼儿: 如果不加UTF-8处理的话中文加密后会全是乱码
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: 正常情况加密的时候没必要utf-8处理的,你为什么要加这一步?而且你这代码有点乱啊
11 个月之前 回复
qq_31520675
qq_31520675 其中对datastr进行UTF-8处理时就是刚开始内种处理方法,但是有一次再解开之后发现其中一部分中午成为乱码,应该是在加密时出现问题,我手动在map里试过各种中午,发现“在”字出现乱码的几率很大
11 个月之前 回复
qq_31520675
qq_31520675 这是这一段完整的代码,写在一个servlet里
11 个月之前 回复
welan123123
welan123123   2017.01.13 14:13

你参考一下这个

    String toRSAStr = FormDateReportConvertor.postFormLinkReport(requestMap);
            message1 = EncryDecryUtils.base64Encrypt(message1);//base64(appId=xxx)
            String message2 = toRSAStr;
            message2 = EncryDecryUtils.encryptFromDESBase64(des3Key,message2);// base64(3DES(报文原文)
            String message3 = EncryDecryUtils.base64Encrypt(EncryDecryUtils.md5(toRSAStr.toString().trim() +"&"+ md5Key));//base64(MD5(报文原文+&+ md5Key))
            String message = message1+"|"+message2+"|"+message3;

            System.out.println("==================");                   
            System.out.println(message2);
            System.out.println("==================");
qq_31520675
qq_31520675 回复奔跑的小鱼儿: dataStr里的中午打印出来 不是乱码,问题出在加密后的报文,和正确报文不一样,也就是说我在Test里用这段代码加密后的报文和servlet里加密的报文不一样
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: dataStr 里的中文就是乱码了吗?
11 个月之前 回复
qq_31520675
qq_31520675 回复奔跑的小鱼儿: 你说的有点道理,我这部分servlet是接受到的报文,对报文进行解密处理之后进行二次加工,取出里面的属性和值后,有的值是中文的,如果不加utf-8的话这部分中文的值加密会成乱码
11 个月之前 回复
qq_31520675
qq_31520675 回复奔跑的小鱼儿: 没做URLEncoder,直接将map转换成字符串,然后加密字符串,但是加密字符串这块出了问题,问题具体跟楼上说的差不多,“楼”字也会变成乱码(用我之前的编码放式)
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: 中间这步utf-8处理我认为是不需要的,可能你其他地方出问题了,然后你这里加了个utf-8处理刚好弥补了部分错误,最终导致这种奇怪现象
11 个月之前 回复
welan123123
welan123123 回复qq_31520675: 你在哪看到的乱码啊?你怎么传的?做URLEncoder了吗
11 个月之前 回复
qq_31520675
qq_31520675 这种方式不适合在servlet里面使用,在其他地方没问题,但是servlet里会变成乱码
11 个月之前 回复
qq_31520675
qq_31520675 这个如果不进行编码处理在servlet里是不行的,这个很像我之前不处理UTF-8的代码,结果就是加密后汉子全部乱码
11 个月之前 回复
welan123123
welan123123   2017.01.13 14:21

解密方法

 //对返回的数据 先用base64解密 再用3Des解密
    public static String decryptFromBase64DES(String key,String data) {
        String result = null;
        byte[] keyByte = key.getBytes();
        byte[] base64Byte = EncryDecryUtils.getFromBase64byte(data);
        try {
            result =  new String(DESUtils.Union3DesDecrypt(keyByte,base64Byte),"utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
xiaoleizhanghahaha
xiaoleizhanghahaha   2017.01.13 15:07

加密算法,是不是你们公司自己的一套算法。

xiaoleizhanghahaha
xiaoleizhanghahaha 回复qq_31520675:debug下看看,把你项目中导进去的所有文件进行统一编码。改成和你用的开发工具编码一致,
11 个月之前 回复
qq_31520675
qq_31520675 这只是一套比较工卡的加密算法、
11 个月之前 回复
qq_31520675
qq_31520675   2017.01.13 15:34
     public static String postFormLinkReport(Map<String,String> dataMap){

        StringBuilder reportBuilder = new StringBuilder();

        List<String> keyList = new ArrayList<String>(dataMap.keySet());
        Collections.sort(keyList);

        for(String key : keyList){
            reportBuilder.append(key+"="+dataMap.get(key)+"&");
        }

        reportBuilder.deleteCharAt(reportBuilder.lastIndexOf("&"));

        return reportBuilder.toString();
    }
qq_31520675
qq_31520675   2017.01.13 15:45

这段代码是处理属性值的,从解密好的字符串中将代码分割,先以&分割再以=号分割

                String[] str4 = srt.split("\\&");
                    for (int i = 0; i < str4.length; i++) {
                         if("mhtOrderNo".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             mhtOrderNo=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("mhtReqTime".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             mhtReqTime=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("payeeAccType".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             payeeAccType=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("payeeName".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             payeeName=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();

                         }
                         if("payeeCardNo".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             payeeCardNo=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("payeeCardUnionNo".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             payeeCardUnionNo=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("mhtOrderAmt".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             mhtOrderAmt=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
                         if("agentPayMemo".equals(str4[i].toString().split("\\=")[0].toString()))
                         {
                             agentPayMemo=str4[i].toString().split("\\=")[1].toString().replaceAll("\0", "").trim();  
                         }
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!