最近在做一个项目,需要对外暴露两个接口接收别人给的参数,但是有一个问题就是对方的项目是一个老项目,在传参数的时候是将多个字符放在一个参数里面用“|”进行分割,然而他们传参数的时候又没有对“|”进行url编码这个时候他们用这个url访问我们会导致服务器一致报400的错误,而对方如果要改这个东西又很慢很麻烦,所以我百度了很久发现tomcat有一个很坑的设置就是默认会在url中有特殊字符的时候拦截并且报400。

  如果我们要关闭这个设定需要到tomcat的conf目录下找到catalina.properties这个配置文件,滑到最顶端有一个被注释掉的配置(此处我已经把注释去掉了),你可以在这个配置中添加你不想让tomcat拦截的特殊字符,重启tomcat服务,之后你会发现网页就不会再报错了。

顺带一提,对方在传参的时候还有一个坑,就是使用escape的方式对中文字符加密以后再进行传输,然后jsp和servlet又无法接受到被这个加密之后的参数,收到的参数不是空字符串,而是直接为null(好吧,不如直接说根本就没接收到)。

解决方案:

  1、换编码方式

  2、要对字符串用escape加密两次之后传到控制层中,再使用我网上查到的一个工具类进行解密。

  3、而这个对面由于要兼容多个公司的软件所以不能修改,为了解决这个问题,我使用request.getQueryString()这个方法直接获得url问号后面所有的字符,然后再进行的操作。

这边我直接把别人写好的工具类复制过来,以供大家参考。

  1
2 /**
3 * 对js中escape编码后 进行解码
4 *
5 */
6 public class EscapeUtils {
7
8 /** The Constant hex. */
9 private final static String[] hex = { "00", "01", "02", "03", "04", "05",
10 "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10",
11 "11", "12", "13", "14", "15", "16", "17", "18", "19", "1A", "1B",
12 "1C", "1D", "1E", "1F", "20", "21", "22", "23", "24", "25", "26",
13 "27", "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", "30", "31",
14 "32", "33", "34", "35", "36", "37", "38", "39", "3A", "3B", "3C",
15 "3D", "3E", "3F", "40", "41", "42", "43", "44", "45", "46", "47",
16 "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", "50", "51", "52",
17 "53", "54", "55", "56", "57", "58", "59", "5A", "5B", "5C", "5D",
18 "5E", "5F", "60", "61", "62", "63", "64", "65", "66", "67", "68",
19 "69", "6A", "6B", "6C", "6D", "6E", "6F", "70", "71", "72", "73",
20 "74", "75", "76", "77", "78", "79", "7A", "7B", "7C", "7D", "7E",
21 "7F", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
22 "8A", "8B", "8C", "8D", "8E", "8F", "90", "91", "92", "93", "94",
23 "95", "96", "97", "98", "99", "9A", "9B", "9C", "9D", "9E", "9F",
24 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "AA",
25 "AB", "AC", "AD", "AE", "AF", "B0", "B1", "B2", "B3", "B4", "B5",
26 "B6", "B7", "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", "C0",
27 "C1", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "CA", "CB",
28 "CC", "CD", "CE", "CF", "D0", "D1", "D2", "D3", "D4", "D5", "D6",
29 "D7", "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", "E0", "E1",
30 "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC",
31 "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
32 "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" };
33
34 /** The Constant val. */
35 private final static byte[] val = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
36 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
37 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
38 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
39 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x01,
40 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x3F, 0x3F, 0x3F,
41 0x3F, 0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F,
42 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
43 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
44 0x3F, 0x3F, 0x3F, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x3F, 0x3F,
45 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
46 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
47 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
48 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
49 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
50 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
51 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
52 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
53 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
54 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
55 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
56 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
57 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
58 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F };
59
60 /**
61 * Escape.
62 *
63 * @param s
64 * the s
65 *
66 * @return the string
67 */
68 /**
69 * 编码
70 *
71 * @param s
72 * @return
73 */
74 public static String escape(String s) {
75 if (s != null) {
76 StringBuffer sbuf = new StringBuffer();
77 int len = s.length();
78 for (int i = 0; i < len; i++) {
79 int ch = s.charAt(i);
80 if ('A' <= ch && ch <= 'Z') {
81 sbuf.append((char) ch);
82 } else if ('a' <= ch && ch <= 'z') {
83 sbuf.append((char) ch);
84 } else if ('0' <= ch && ch <= '9') {
85 sbuf.append((char) ch);
86 } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!'
87 || ch == '~' || ch == '*' || ch == '\'' || ch == '('
88 || ch == ')') {
89 sbuf.append((char) ch);
90 } else if (ch <= 0x007F) {
91 sbuf.append('%');
92 sbuf.append(hex[ch]);
93 } else {
94 sbuf.append('%');
95 sbuf.append('u');
96 sbuf.append(hex[(ch >>> 8)]);
97 sbuf.append(hex[(0x00FF & ch)]);
98 }
99 }
100 return sbuf.toString();
101 }
102 return null;
103 }
104
105 /**
106 * Unescape.
107 *
108 * @param s
109 * the s
110 *
111 * @return the string
112 */
113 /**
114 * 解码 说明:本方法保证 不论参数s是否经过escape()编码,均能得到正确的“解码”结果
115 *
116 * @param s
117 * @return
118 */
119 public static String unescape(String s) {
120 if (s != null) {
121 StringBuffer sbuf = new StringBuffer();
122 int i = 0;
123 int len = s.length();
124 while (i < len) {
125 int ch = s.charAt(i);
126 if ('A' <= ch && ch <= 'Z') {
127 sbuf.append((char) ch);
128 } else if ('a' <= ch && ch <= 'z') {
129 sbuf.append((char) ch);
130 } else if ('0' <= ch && ch <= '9') {
131 sbuf.append((char) ch);
132 } else if (ch == '-' || ch == '_' || ch == '.' || ch == '!'
133 || ch == '~' || ch == '*' || ch == '\'' || ch == '('
134 || ch == ')') {
135 sbuf.append((char) ch);
136 } else if (ch == '%') {
137 int cint = 0;
138 if ('u' != s.charAt(i + 1)) {
139 cint = (cint << 4) | val[s.charAt(i + 1)];
140 cint = (cint << 4) | val[s.charAt(i + 2)];
141 i += 2;
142 } else {
143 cint = (cint << 4) | val[s.charAt(i + 2)];
144 cint = (cint << 4) | val[s.charAt(i + 3)];
145 cint = (cint << 4) | val[s.charAt(i + 4)];
146 cint = (cint << 4) | val[s.charAt(i + 5)];
147 i += 5;
148 }
149 sbuf.append((char) cint);
150 } else {
151 sbuf.append((char) ch);
152 }
153 i++;
154 }
155 return sbuf.toString();
156 }
157 return null;
158 }
159
160 }

tomcat拦截特殊字符报400,如 "|" "{" "}" ","等符号的解决方案的更多相关文章

  1. SpringBoot解决特殊符号 []报400问题

    当遇到特殊符号传递给后台时,如果不加处理,就会报400的错误,解决办法有两种. 1.前台解决 前台解决的方法就是把这些特殊符号转义,转义之后浏览器和后台都可以识别. //对特殊字符进行转义 encod ...

  2. springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本 get请求报400 异常信息为 The valid characters are defined in RFC 7230 and RFC 3986

    1.springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本而之前用的是tomcat7    get请求报400 异常信息为 The valid characters are ...

  3. tomcat8 url包含|等特殊字符报错400的问题

    这个问题纠缠了我很久了,终于在今天早上解决了,感谢自己的不放弃和不断尝试的决心,我坚信,我可以找到解决方式!! 项目用的spring .spring mvc.hibernate框架,关于统一错误页面在 ...

  4. nginx+tomcat报400的坑

    nginx+tomcat的网页,在手机上通过浏览器可以正常访问,但是在自己的app的webview中访问就报400.查了访问日志,每次app中访问该页面,tomcat中就出现一个GET null的申请 ...

  5. tomcat8踩坑:url包含|等特殊字符报错400的问题

    这个问题纠缠了我很久了,终于在今天早上解决了,感谢自己的不放弃和不断尝试的决心,我坚信,我可以找到解决方式!! 项目用的spring boot+spring security框架,关于统一错误页面在开 ...

  6. Tomcat8升级后URL中特殊字符报错出现原因

    请求带上花括号等字符,请求无法送达服务端,报错: Failed to load resource: the server responded with a status of 400 () https ...

  7. IE浏览器报400错误:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

    前言: 在用IE浏览器时访问tomcat项目时,页面报400错误,后台错误: java.lang.IllegalArgumentException: Invalid character found i ...

  8. 【原】tomcat 7 启动报错:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig()Ljavax/servlet/SessionCookieConfig的解决

    现象: tomcat 7 启动报错:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getSessionCookieConfig() ...

  9. javaweb 拦截器报错

    拦截器报错   The content of element type "interceptor-ref" must match "(param)*".内容元素 ...

随机推荐

  1. Relocations in generic ELF (EM: 40)

    最近在搞机器上的wifi热点,需要移植一大堆东西,如hostapd\wpa_suppliant.dhcp等,这些玩意又依赖其他的一大堆库的移植,比如libnl,openssl等,今天在移植编译libn ...

  2. zabbix 报警发送qq邮件

    1.开启QQ邮箱的IMAP/SMTP服务,获取授权码 获取授权码:点击[开启]按钮,编辑短信发送,即可获得授权码 2.配置 /etc/mail.rc 添加下列配置: [ set from=XXX@qq ...

  3. Redis去重方法

    目录 1.基于 set 2.基于 bit 3.基于 HyperLogLog 4. 基于bloomfilter 这篇文章主要介绍了Redis实现唯一计数的3种方法分享,本文讲解了基于SET.基于 bit ...

  4. c++ template 实现一个简单的"栈"

    一: 实现一个简单的swap 原来我们写swap一定会这样写: 对于int类型的: swap(const int &x,const int &y) { int temp; temp = ...

  5. 2019年java大型项目技术选型

    学习一下 1,公司使用的架构是:SpringCloud + K8S 这一套主流技术,但是还是入门级别的. 还包含apollo  ,xxlJob ,SkyWalking,Cat,GrayLog等 2,G ...

  6. elasticsearch在postman中创建复杂索引

    body,所选类型为raw和JSON,写的代码为 { "settings":{ "number_of_shards":1, "number_of_re ...

  7. 12组-Alpha冲刺-1/6

    一.基本情况 队名:字节不跳动 组长博客:https://www.cnblogs.com/147258369k/p/15526363.html 小组人数:10人 二.冲刺概况汇报 侯钦凯 过去两天完成 ...

  8. 体验用yarp连接websocket

    前段时间一看yarp的仓库,wow,终于发布1.0版本了..net也升级到6版本了,之前一直只是用yarp做HTTP转发,今天刚好试试websocket 话不多说,直接开搞 配置集群 首先先配置集群信 ...

  9. Docker部署 Mysql .Net6等容器

    Centos8安装Docker 1.更新一下yum [root@VM-24-9-centos ~]# yum -y update 2.安装containerd.io # centos8默认使用podm ...

  10. win8中让cmd.exe始终以管理员身份运行

    最近在学习配置本地服务器,在命令行启动mysql时总是由于权限不足而失败, Win+R -- cmd ,这样总是不能,还要找到cmd.exe右键以管理员身份运行cmd,再 net start mysq ...