最近在做一个项目,需要对外暴露两个接口接收别人给的参数,但是有一个问题就是对方的项目是一个老项目,在传参数的时候是将多个字符放在一个参数里面用“|”进行分割,然而他们传参数的时候又没有对“|”进行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. gawk使用方法简介

    转载:gawk 使用方法简介 - 简书 (jianshu.com) gawk 是最初 Unix 系统上 awk 程序的 GNU 版本.相对于作为流式编辑器的 sed 而言,它提供了更为强大的编程语言特 ...

  2. C#写TXT文档

    //C#写TXT文档 String strDir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAs ...

  3. S 锁与 X 锁的爱恨情仇《死磕MySQL系列 四》

    系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强 ...

  4. LINUX系统新增及自动挂载硬盘-九五小庞

    Linux系统下,添加新硬盘后,自动挂载的方法   1,列出所有硬盘,找到需要挂载的硬盘,例如/dev/vdb.输入: fdisk -l   2,查看硬盘是不是已经被挂载.一个硬盘不能重复挂载,已经挂 ...

  5. 2021.11.2-测试T1数独

    痛苦 题目 数 独 [问题描述] 给定一个9*9矩阵,对其进行几种操作,分别是插入,删除,合并,查询,输出 主要学到了一些特别的操作. (1)备份( 本蒟蒻第一次了解到) (2)对与数据的一些特别的改 ...

  6. java核心技术 第3章 java基本程序设计结构

    类名规范:以大写字母开头的名词 若由多个单词组成 每个单词的第一个字母应大写(驼峰命名法)  与.java文件名相同 运行程序:java ClassName(dos命令) 打印语句:System.ou ...

  7. .NET 开源工作流: Slickflow流程引擎高级开发(九) -- 条件事件模式解释及应用

    前言:在流程流转过程中,有时候需要条件模式的支持,这样可以使得流程流转更加灵活多变.比如在业务变量满足一定的条件时,可以启动特定配置的流程(或者位于主流程内部的子流程).本文主要描述条件启动和条件中间 ...

  8. robot_framewok自动化测试--(4)常用关键字介绍

    常用关键字介绍 在学习一门编程语言的时候,大多教材都是从打印"hello world"开始.我们可以像编程语言一样来学习 Robot Framework.虽然通过 RIDE 提供& ...

  9. 03 | 变量的解构赋值 | es6

    变量的解构赋值 数组的解构赋值 基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 以前,为变量赋值,只能直接指定值. let a ...

  10. 力扣 - 剑指 Offer 59 - I. 滑动窗口的最大值

    题目 剑指 Offer 59 - I. 滑动窗口的最大值 思路1(单调队列) 使用单调(递减)队列,保持队列中的元素是递减顺序,队列头保存的是当前窗口中最大的元素 首先先模拟建立第一个窗口,同时获取第 ...