eggjs 如何方便的获取multipart 参数

eggjs 自身的multipart 解析

eggis 有两大特点:

  1. 懒解析:只有在主动调用时, 比如this.multipart, 才会解析multipart 请求。
  2. 流式stream处理:如果想在拿到fd 文件前得到fields, fd 就必须放在fields 之后。

Stream 能让server 性能更好。但是这也给开发带来了不便。

  1. 处理 fd 之前,不能提前获得fields
  2. fd stream 必须消费掉,否则连接不会关闭, 浏览器pending.

统一处理

可以参考下面的方法,统一解析出 fields, 并消费掉stream.

// app/core/base_controller.js
const app = require('egg');

module.exports =
  app.BaseController =
  class BaseController extends app.Controller {
    rest(rest) {
      this.ctx.body = typeof rest === 'object' ? rest : JSON.stringify(rest)
      this.ctx.type = 'application/json';
    }

    throw(msg) {
      msg = msg || 'unknown';
      this.ctx.throw(400, msg);
    }

     async multipart() {
      const tmp = require('tmp')
      const fs = require('fs')
      const ctx = this.ctx
      const files = [];
      ctx.files = files
      let fields, part;
      if (this.ctx.get('Content-Type').startsWith('multipart/')) {
        try {
          // const file = await ctx.getFileStream()
          // files.push(file);
          // fields = stream.fields;
          // const sendToWormhole = require('stream-wormhole');
          // let result = await ctx.oss.put('egg-multipart-test/' + part.filename, part);
          // await sendToWormhole(part);
          const parts = ctx.multipart({ autoFields: true });
          while ((part = await parts()) != null) {
            if (part.length) {
            } else if (part.filename) {
              const tmpFile = tmp.fileSync({prefix: 'eggjs-upload-'})
              const ws = fs.createWriteStream(null, {fd:tmpFile.fd})
              part.pipe(ws)
              part.path = tmpFile.name
              part.fd = tmpFile.fd
              files.push(part)
            }
          }
          fields = parts.field
        } catch (err) {
          //await sendToWormhole(part);
          throw err;
        }
      }
      return [files, fields];
    }
  }

使用时,直接可获取到上传的文件+fields:

      const [files, fields] = await this.multipart();

另外为了及时清理临时文件,我设置了 ctx.files 存放临时文件。
然后通过中间件middleware 在请求最后及时清理:

  if (ctx.files && ctx.files.length) {
    for (let file of ctx.files) {
      if (file.path && fs.existsSync(file.path)) {
        fs.unlinkSync(file.path)
      }
    }
  }

加载baseController

显然,默认情况下,node 不支持项目根目录加载:

require('core/base_controller')

我们需要在app.js 里面设置:NODE_PATH

let path = require('path')
process.env.NODE_PATH = path.resolve(__dirname, 'app/') ;
require('module').Module._initPaths();

或者在命令行直接设置: NODE_PATH=$PWD/app egg-bin dev

vscode 自动补全

vscode 可不知道你设置了NODE_PATH, 所以 vsc 也找不到module. 我们需要再项目根目录中通过jsconfig.json 告诉vsc 去base_dir 找module.

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "baseUrl": "./app"
  },
  "exclude": [
    "node_modules"
  ]
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java中,使用Multipart参数传递可以通过多种方式实现。其中一种常见的方式是使用MultipartEntity类来构建Multipart参数,然后将其添加到HttpPost请求中。 首先,我们可以创建一个MultipartEntity对象,并使用addPart方法添加Multipart参数,如文件或文本字段。例如: ```java MultipartEntity entity = new MultipartEntity(); File file = new File("example.txt"); entity.addPart("file", new FileBody(file, "text/plain")); entity.addPart("field1", new StringBody("value1", ContentType.TEXT_PLAIN)); ``` 接下来,我们可以创建一个HttpPost请求,并将MultipartEntity对象作为请求实体添加到请求中,然后执行该请求,发送Multipart参数。例如: ```java HttpPost postRequest = new HttpPost("http://example.com/upload"); postRequest.setEntity(entity); HttpClient httpClient = HttpClientBuilder.create().build(); HttpResponse response = httpClient.execute(postRequest); ``` 以上代码示例使用了Apache HttpClient库来发送HTTP请求,其中HttpPost类表示一个HTTP POST请求,MultipartEntity对象表示Multipart参数。通过执行该请求,Multipart参数将被传递到指定的URL。 另外,在Spring框架中,可以使用MultipartFile类来接收Multipart参数。例如,在控制器的方法参数中使用MultipartFile类型的参数接收文件上传,然后进行相应的处理。 总之,Java中Multipart参数的传递可以通过构建MultipartEntity或使用相关库提供的工具类来实现,具体方式取决于项目需要和使用的技术栈。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值