http delete method请求经过zuul网关requestbody为空问题处理

最近我们在做微服务网关升级,因为我们的架构体系采用的Spring Boot+Spring Cloud,所以网关这块就直接采用Netflix的Zuul。做完网关升级后,测试同学在做系统回归测试,发现在调用一个http接口使用restful的delete method并带有request body的请求时,我们的业务微服务应用报错了:

org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing

看到这个报错,第一反应是自己本地启动业务微服务测试,发现一切安好。考虑到测试环境的请求是先经过Zuul网关,网关再将请求转发到微服务,所以问题应该出现网关层。于是本地启动网关,让请求先经过本地的网关再到本地微服务,发现bug复现了。bug复现了就好办了,接下来调试网关的源码,在spring-cloud-netflix-core-1.4.4.RELEASE.jar包下面的RibbonRoutingFilter类中找到一段代码如下

其中的RibbonCommand有一个抽象实现类AbstractRibbonCommand,它又有三个子类:HttpClientRibbonCommand、OkHttpRibbonCommand、RestClientRibbonCommand。我们系统在application.properties里配置的httpclient如下:

ribbon.restclient.enabled=true

所以RibbonCommand此时使用的实现类是RestClientRibbonCommand,查看了源码:

上图中红色框部分,如果请求的Method是Delete,就将requestEntity设置为null,所以这就是为什么我们的业务微服务在网关转发了请求后得不到requestbody的原因。

那么为什么这个RestClientRibbonCommand类会把requestEntity设置为null呢?业界在Restful服务中Delete请求能否使用Entity body也是众说纷纭,有些http client支持有些又不支持,既然我们用的RestClientRibbonCommand不支持那么我们就换成OkHttpRibbonCommand或者HttpClientRibbonCommand呗。

于是我们最终在application.properties里将配置的httpclient改成:

# ribbon.restclient.enabled=true
ribbon.okhttp.enabled = true

重启服务,测试,解决问题。

PHP过滤非法字符(判断Kindereditor内容是否为空)

之前在网上找到一段PHP过滤非法字符的代码:

function safe_string($str)
{ //过滤安全字符
$str=str_replace("'","",$str);
$str=str_replace('"',"",$str);
$str=str_replace(" ","$nbsp;",$str);
$str=str_replace("\n;","
",$str);
$str=str_replace("<","<",$str);
$str=str_replace(">",">",$str);
$str=str_replace("\t"," ",$str);
$str=str_replace("\r","",$str);
$str=str_replace("/[\s\v]+/"," ",$str);
return $str;
}

后来在工作中,我使用Kindereditor的时候出现了一些问题,在编辑器中出现内容为空白的情况下,其实很多时候内容不一定为空,因为很可能还有隐藏的HTML标签存在,点击编辑器左上角的“HTML代码”就可以看到HTML标签了。那么怎么样判断是否出现这样的情况呢?

我的想法是先剥掉HTML的标签,然后去掉一空格、换行和制表符之后判断这个字符串是否为空即”。以下是判断的代码:

function safeString($str)
{ //过滤字符
 $str=strip_tags($str);    //剥掉HTML标签
 //去掉单双引号、空格、换行、制表符和 
 $str=str_replace("'","",$str);
 $str=str_replace('"',"",$str);
 $str=str_replace(" ","",$str);
 $str=str_replace("\n","",$str);
 $str=str_replace("\t"," ",$str);
 $str=str_replace("\r","",$str);
 $str=str_replace(" ","",$str);
 return $str;
}

使用以上函数过滤字符串之后,再判断字符串$str是否为空,即if($str==”),就完成这个判断了。