springboot奇怪问题【1】—— HttpServletRequest和@Async搭配使用


HttpServletRequest和@Async搭配使用问题

问题描述:希望将request中参数传递到service中处理,同时service是使用异步@Async,此时通过request.getParameterMap()获取参数列表只能在程序启动第一次才能获取到,第二次及之后获取为空,测试如果去掉@Async注解则每次都能获取到参数.

// Controller层
@GetMapping("/call")
public String callback(HttpServletRequest request) {
    // 这是一个异步方法
    service.call(request.getParameterMap());
    return "ok";
}
// Service层
@Async
public String call(Map<String, String[]>extras) {
    //todo 
    // 对extras做处理
    return "ok";
}

问题解决

// Controller层
@GetMapping("/call")
public String callback(HttpServletRequest request) {
    // 需要创建一个新的map,将request中参数导入,再传递到异步方法中
    Map<String, String[]> extras = new HashMap<>();
    extras.putAll(request.getParameterMap());
    service.call(extras);
    return "ok";
}

原因分析

  • request.getParameterMap()返回的是一个Map类型的值,该返回值记录着前端所提交请求中的请求参数和请求参数值的映射关系。这个返回值有个特别之处——只能读。不像普通的Map类型数据一样可以修改。这是因为服务器为了实现一定的安全规范,所作的限制。

  • 如果实在有必要在取得此值以后做修改的话,要新建一个map对象,将返回值复制到此新map对象中进行修改,用新的map对象代替使用之前的返回值。

  • 源码分析

    // Collections.unmodifiableMap()方法使得集合为只读。
    public Map getParameterMap() {
      Map result = new HashMap();
      if (!this.paramsSnapshot.isEmpty()) {
          result.putAll(this.paramsSnapshot);
      }
      result.putAll(super.getParameterMap());
      return Collections.unmodifiableMap(result);
    }

文章作者: wuzhiyong
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wuzhiyong !
评论
 上一篇
通过ftp上传文件到centos中文文件名乱码问题 通过ftp上传文件到centos中文文件名乱码问题
问题描述在windows上使用ftp上传文件到Linux上,中文名称在Linux系统中显示为乱码。 原因在于,Windows 的文件名中文编码默认为GBK,压缩或者上传后,文件名还会是GBK编码,而Linux中默认文件名编码为UTF8,由于
2020-10-22
下一篇 
java插件化设计开发 java插件化设计开发
问题java实现动态从jar包加载插件并运行. 实现 定义插件运行的接口,用户需要自己实现的 public interface PluginService { /** * 插件运行方法 */ void process()
2020-09-29
  目录