otale / tale

🦄 Best beautiful java blog, worth a try
https://tale.biezhi.me
MIT License
4.86k stars 1.5k forks source link

发布文章,包含“=”、“&”,导致无法保存 #578

Closed cuitpanfei closed 1 year ago

cuitpanfei commented 4 years ago

登录后台后,撰写文章,由于部分描述需要code,于是插入了代码片段。 结果保存时,发现后台报错了。 io.netty.handler.codec.http.multipart.HttpPostRequestDecoder$ErrorDataDecoderException: java.io.IOException: Unable to create temporary file, C:\Users\pys1714\AppData\Local\Temp\Attr_7771572786958116046_{"cid":4,"title": 看见报错,我一开始以为保存时的策略是缓存为文件,而且对数据长度有限制,我就开始删文字,并且debug。我发现好像并没有临时文件生成。于是怀疑是某种原因导致的要去创建文件。

根据报错,找到底层方法io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.parseBodyAttributes()

观察方法后发现是netty在读取我传入的数据,然后一个个char的方式在做某种判断。

switch (currentStatus) {
case DISPOSITION:// search '='
     // other code
    break;
case FIELD:// search '&' or end of line
    // other code
    break;
default:
    // just stop
    sao.setReadPosition(0);
    contRead = false;
    break loop;
}

我注意到注释说要查询两个字符“=”,“&”。怀着试一试的方法,我本次文章只包含了“=”,点击保存,果然报错: io.netty.handler.codec.http.multipart.HttpPostRequestDecoder$ErrorDataDecoderException: java.io.IOException: 文件名、目录名或卷标语法不正确。 我又尝试了“&”,也是如此。

我目前还没有具体解决方案,因为这个出错的地方是netty的私有方法。

cuitpanfei commented 4 years ago

已找到解决方案,https://juejin.im/post/5c63a028f265da2d9262c662

具体方法就是,

  1. src/main/java下创建包:io.netty.handler.codec.http.multipart

  2. 从netty-codec-http-4.1.30.Final.jar对应的源码中找到HttpPostStandardRequestDecoder.java

  3. 复制源码到第一步创建的包下

  4. 找到parseBodyAttributes(),再方法第一行添加上如下代码:

    if(!this.request.headers().get("Content-Type").startsWith(APPLICATION_X_WWW_FORM_URLENCODED)){
          return;
    }
  5. 使用maven package命令打包tale

zhoukuansky commented 4 years ago

嗯嗯 找了很久发现是Blade底层报错。内心是崩溃的。先尝试下你的方法。谢谢

zhoukuansky commented 4 years ago

感谢你的方法 但是通过阅读代码 并没有读懂原理。。表示懵懂

zheng-zy commented 4 years ago

升级一下Blade netty的依赖 `

io.netty
        <artifactId>netty-codec</artifactId>
        <version>4.1.31.Final</version>
    </dependency>`
zhoukuansky commented 4 years ago

升级一下Blade netty的依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-codec</artifactId> <version>4.1.31.Final</version> </dependency>

试了一下,表示无法解决问题。。。

comenice commented 4 years ago

已找到解决方案,https://juejin.im/post/5c63a028f265da2d9262c662

具体方法就是,

  1. src/main/java下创建包:io.netty.handler.codec.http.multipart
  2. 从netty-codec-http-4.1.30.Final.jar对应的源码中找到HttpPostStandardRequestDecoder.java
  3. 复制源码到第一步创建的包下
  4. 找到parseBodyAttributes(),再方法第一行添加上如下代码:
if(!this.request.headers().get("Content-Type").startsWith(APPLICATION_X_WWW_FORM_URLENCODED)){
          return;
}
  1. 使用maven package命令打包tale
if(!this.request.headers().get("Content-Type").startsWith(APPLICATION_X_WWW_FORM_URLENCODED)){
          return;
}

这个参数为 下↓

if(!this.request.headers().get("Content-Type").startsWith("application/x-www-form-urlencoded")){
            return;
 }

完美解决 👍 A(G1% (QH{7~MTO)O438YC5 A(G1% (QH{7~MTO)O438YC5