记录一些问题

news2024/11/29 10:57:44

1、如何下载从数据库中查询出来的数据

查询结果List 写到文件中,然后下载

 @GetMapping(value = "/download")
    public void download(HttpServletResponse response)
            throws IOException {
        List<ticket> tickets = getTickets();
        File tmpFile = write2CSVFile(tickets);
             
        final String fileName = tmpFile.getName();
        response.setCharacterEncoding("UTF-8");
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Content-Disposition",
                           "attachment;filename=" + fileName);
        FileUtils.readToOutputStream(tmpFile.getPath(),
                                     response.getOutputStream(), 0);
        response.getOutputStream().close();
    }

FileUtils

 /**
     * @param filePath    path of the file which work as the input source
     * @param outputStream the OutputStream to which the data is written
     * @param skippedSize  the size of the bytes which is skipped for every file
     */
    public static OutputStream readToOutputStream(
            String filePath, OutputStream outputStream,
            long skippedSize) throws IOException {
        int bytesRead;
        BufferedOutputStream bufferedOutputStream =
                new BufferedOutputStream(outputStream);
        byte[] buffer = new byte[1024 * 1024];

        try (BufferedInputStream inputStream =
                     new BufferedInputStream(
                             new FileInputStream(filePath))) {
            inputStream.skip(skippedSize);
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                bufferedOutputStream.write(buffer, 0, bytesRead);
            }
        }

        bufferedOutputStream.flush();
        return bufferedOutputStream;
    }

2、mybatis plus in 参数个数超过限制报错

mybatis plus in 参数个数限制1000条。
解决办法:
in 大集合 改为 多个in 小集合
即分多个in 用or连接

notIn同理,
notIn分为多个 notIn 用and连接

   // run sql
            LambdaQueryWrapper<Ticket> lambdaQueryWrapper =
                    new LambdaQueryWrapper<>();
            // mybatis plus in 参数个数超过限制报错
            try {
                cutInParameter(lambdaQueryWrapper, Ticket::getOneId,
                               oneIdListWithWhitelist);
            } catch (Exception e) {
                log.error("cut parameter fail", e);
                throw new BusinessException("cut parameter fail");
            }
  public static <T, F> void cutInParameter(LambdaQueryWrapper<T> wrapper,
                                             SFunction<T, ?> column,
                                             List<F> coll) throws Exception {
        List<List<F>> newList = splitList(coll, 900);
        if (ObjectUtils.isEmpty(newList)) {
            return;
        } else if (newList.size() == 1) {
            wrapper.notIn(column, newList.get(0));
            return;
        }
        wrapper.and(i -> {
            i.notIn(column, newList.get(0));
            newList.remove(0);
            for (List<F> objects : newList) {
                i.and(w -> {
                    w.notIn(column, objects);
                });
            }
        });
    }

    public static <T> List<List<T>> splitList(List<T> list, int groupSize) {
        int length = list.size();
        // 计算可以分成多少组
        int num = (length + groupSize - 1) / groupSize;
        List<List<T>> splitList = new ArrayList<>(num);
        for (int i = 0; i < num; i++) {
            // 开始位置
            int fromIndex = i * groupSize;
            // 结束位置
            int toIndex = Math.min((i + 1) * groupSize, length);
            splitList.add(list.subList(fromIndex, toIndex));
        }
        return splitList;
    }

3、springboot 自定义类加载器

利用springboot的maven插件打包jar,在java -jar运行时,会采用springboot自定义的类加载器来加载类,使用的是LaunchedURLClassLoader,(使用assembly插件不会有这个问题),
但是代码在IDEA中能够运行,但是打包成jar之后无法运行,报ClassCastException

类的唯一性如何确定:
由加载这个类的类加载器和类本身来唯一确定一个类,也就是说类相同,但是类加载器不同也会被认为是不同的类。

  • 类加载器相同,指的是同一个类加载器对象(不同实例也是不同的类加载器),而不是类加载器的类相同

在业务代码中我们可能需要加载外部指定路径的jar,加载jar时我们一版使用java.net.URLClassLoader,此时如果存在外部jar和springboot加载的类之间有关联,比如有一个类两个类加载器都加载了,那么会被认为是不同的类,由此可能引起ClassCastException

在IDEA中能运行的原因是:在IDEA中统一使用了AppClassLoader这个加载器,这个加载器也称为系统类加载器。
类加载器双亲委派机制
每个加载器加载的位置不同。

一般会使用的方式,url类似 file:/path/to/jar


 private URLClassLoader loader;

 private Properties props = new Properties();
    
  public void loadJar(URL url) throws IOException {

        loader = new URLClassLoader(new URL[]{url});

        try (InputStream stream = loader
                .getResourceAsStream(AdaptorPropsList.HIGHFLIP_PROPERTIES_FILE)) {

            if (stream != null) {
                props.load(stream);
            } else {
                log.info("Missed {} property file.", AdaptorPropsList.HIGHFLIP_PROPERTIES_FILE);
            }
        }
    }

springboot 使用LaunchedURLClassLoader来加载类,此时加载外部jar包用java.net.URLClassLoader,这样类加载器不一致,会引发问题,正确的加载类的方式:

 public void loadJar(URL url) throws IOException {

      private LaunchedURLClassLoader loader = (LaunchedURLClassLoader) Thread.currentThread()
                                                .getContextClassLoader();
        try {
            Method addURL =
                    LaunchedURLClassLoader.class.getSuperclass()
                                                .getDeclaredMethod("addURL",
                                                                   new Class[] {URL.class});
            addURL.setAccessible(true);
            addURL.invoke(loader, new Object[] {url});
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
}

获取当前线程的类加载器

Thread.currentThread().getContextClassLoader()

在这里插入图片描述

LaunchedURLClassLoader类所在的依赖包

 <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-loader</artifactId>
</dependency>

LaunchedURLClassLoader部分源码

public class LaunchedURLClassLoader extends URLClassLoader {
   private static final int BUFFER_SIZE = 4096;
   private final boolean exploded;
   private final Archive rootArchive;
   private final Object packageLock;
   private volatile LaunchedURLClassLoader.DefinePackageCallType definePackageCallType;

   public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) {
       this(false, urls, parent);
   }

   public LaunchedURLClassLoader(boolean exploded, URL[] urls, ClassLoader parent) {
       this(exploded, (Archive)null, urls, parent);
   }

   public LaunchedURLClassLoader(boolean exploded, Archive rootArchive, URL[] urls, ClassLoader parent) {
       super(urls, parent);
       this.packageLock = new Object();
       this.exploded = exploded;
       this.rootArchive = rootArchive;
   }
   
...
}

源码中可以看到

  • LaunchedURLClassLoader没有提供addURL的方法来加载指定路径的jar包
  • LaunchedURLClassLoader继承了URLClassLoader
  • URLClassLoader提供了addURL的方法,但是是protected方法,调用不到

为了能调用addURL方法,采用反射机制来调用,先反射拿到LaunchedURLClassLoader.class类,再getSuperclass()拿到URLClassLoader的类对象,添加url,完成加载外部指定路径的jar包。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/951773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python的os.walk()函数使用案例

在Python中&#xff0c;os模块是一个非常实用的工具&#xff0c;它可以让我们与操作系统进行交互&#xff0c;操作文件和目录。在本文中&#xff0c;我们将详细介绍os模块中的遍历文件功能&#xff0c;并通过具体案例和使用场景来解释。 首先&#xff0c;导入os模块。在Pytho…

嵌入式学习之exec族函数

今天&#xff0c;主要学习的内容是exec族函数和system函数&#xff0c;以及system函数和fork函数的配合使用。今日写的代码如下&#xff1a;

《Kubernetes部署篇:Ubuntu20.04基于containerd部署kubernetes1.24.17集群(多主多从)》

一、架构图 如下图所示: 二、环境信息 1、部署规划主机名K8S版本系统版本内核版本IP地址备注k8s-master-631.24.17Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.63master节点 + etcd节点k8s-master-641.24.17Ubuntu 20.04.5 LTS5.15.0-69-generic192.168.1.64master节点 + …

Linux禅道上修改Apache 和 MySQL 默认端口号

1. 修改Apache默认端口号 80 cd /opt/zbox/etc/apachevim httpd.conf :wq 保存 2. 修改MySQL默认端口号 3306 cd /opt/zbox/etc/mysql vim my.cnf :wq 保存 3. 重启服务 ./zbox restart

计算机网络-笔记-第六章-应用层

目录 六、第六章——应用层 1、应用层概述 2、(C/S)客户-服务器方式 & &#xff08;P2P&#xff09;对等方式 &#xff08;1&#xff09;客户-服务器方式【C/S】 &#xff08;2&#xff09;对等方式【P2P】 3、DHCP——动态主机配置协议 &#xff08;1&#xff09;诞…

面试结束后:如何写一封有效的感谢信

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

开源且强大的网络嗅探分析工具——Wireshark

Wireshark是一款强大的开源网络协议分析工具&#xff0c;旨在帮助用户深入了解网络通信的细节。通过捕获、解析和展示网络数据包&#xff0c;Wireshark能够帮助工程师诊断问题、优化性能&#xff0c;以及解决各种网络难题。无论是深入分析还是快速调试&#xff0c;Wireshark都是…

学习pytorch7 神经网络的基本骨架--nn,module的使用

神经网络的基本骨架--nn,module的使用 官网Module介绍Python父类子类继承关系前向神经网络pycharm快捷键重写类方法codedebug B站小土堆视频学习笔记 官网Module介绍 https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module Python父类子类继承关系…

4.4 对幻灯片进行动画制作

动画是演示文稿的重要构成要素&#xff0c;WPS演示为用户提供了多种动画类型&#xff0c;通过学习设置页面切换、动画效果等相关功能&#xff0c;可使演示文稿更加生动&#xff0c;富于表现力。 4.4.1 设置页面的切换方式 页面的切换是指从一张幻灯片切换到另一张幻灯片时的页…

【ES6】JavaScript中的Symbol

Symbol是JavaScript中的一种特殊的、不可变的、不可枚举的数据类型。它通常用于表示一个唯一的标识符&#xff0c;可以作为对象的属性键&#xff0c;确保对象的属性键的唯一性和不可变性。 Symbol.for()是Symbol的一个方法&#xff0c;它用于创建一个已经注册的Symbol对象。当…

ThePASS研究院|以Safe为例,解码DAO国库管理

本研究文章由ThePASS团队呈现。ThePASS是一家开创性的DAO聚合器和搜索引擎&#xff0c;在为DAO提供洞察力和分析方面发挥着关键作用。 Intro 随着去中心化自治组织&#xff08;DAOs&#xff09;的发展&#xff0c;它们被赋予了越来越多的角色和期望。在这种巨幅增长的背景下&…

大数据平台与数据仓库的五大区别

随着大数据的快速发展&#xff0c;很多人难以区分大数据平台与数据仓库的区别&#xff0c;两者傻傻分不清楚。今天我们小编就给大家汇总了大数据平台与数据仓库的五大区别&#xff0c;希望有用哦&#xff01;仅供参考&#xff01; 大数据平台与数据仓库的五大区别 一、概念不同…

docker安装grafana,prometheus,exporter以及springboot整合详细教程(GPE)

springboot项目ip:192.168.168.1 测试服务器ip:192.168.168.81 文章来自互联网,自己略微整理下,更容易上手,方便自己,方便大家 最终效果: node springboot 1.下载镜像 docker pull prom/node-exporter docker pull prom/mysqld-exporter docker pull google/cadvisor dock…

微前端-monorepo-无界

文章目录 前言一、微前端二 、monorepo三 、pnpm硬链接软链接&#xff08;符号链接&#xff09;幽灵依赖依赖安装耗时长monorepo项目搭建子模块复用 四、无界接入无界无界预加载无界传参 总结 前言 本文主要记录微前端框架 无界 的使用与理解以及monorepo代码管理方式。 一、微…

小红书群禁言

群禁言在2023上半年炒得沸沸扬扬&#xff0c;结果官方一个关闭接口操作&#xff0c;谁都没办法了 不过还好&#xff0c;现在有了完美的解决方案&#xff1a;群撤回助手&#xff01; 24小时帮你管群&#xff0c;自定义规则、白名单&#xff0c;有广告自动秒撤&#xff01;多发广…

PyQt6 GUI界面设计和Nuitka包生成exe程序(全笔记)

PyQt6 GUI界面设计和Nuitka包,生成exe程序全笔记 目录一、PyQt6包安装1.1 进行环境配置和安装1.2 检查包是否安装成功。1.3 运行desinger.exe二、GUI界面设计,写程序,并能运行成功。三、Nuitka打包生成exe程序3.1 做Nuitka安装准备工作(1)安装C编译器,设置环境变量3.2 安…

Mysql优化原理分析

一、存储引擎 1.1 MyISAM 一张表生成三个文件 xxx.frm&#xff1a;存储表结构xxx.MYD&#xff1a;存储表数据xxx.MYI&#xff1a;存储表索引 索引文件和数据文件是分离的&#xff08;非聚集&#xff09; select * from t where t.col1 30; 先去t.MYI文件查找30对应的索引…

赴日IT 如何提高去日本做程序员的几率?

其实想去日本做IT工作只要满足学历、日语、技术三个必要条件&#xff0c;具备这些条件应聘就好&#xff0c;不具备条件你就想办法具备这些条件&#xff0c;在不具备条件之前不要轻易到日本去&#xff0c;日本IT行业虽然要求技术没有国内那么高&#xff0c;但也不是随便好进入的…

通过RD Client远程连接windows电脑踩坑点

通过RD Client远程连接windows电脑操作的个人踩坑点&#xff0c;记录下来&#xff0c;防止下一次还犯。 配置&#xff1a; win10专业版腾讯云服务器Ubuntu22.04小米平板RD client 首先是安装frp 这一部分参考的是&#xff1a;通过RD Client远程连接windows电脑&#xff08;…

FireFox禁用HTTP2

问题 最近需要调试接口&#xff0c;但是&#xff0c;Chrome都是强制使用h2协议&#xff0c;即HTTP/2协议。为了排除h2协议排除对接口调用的影响&#xff0c;需要强制浏览器使用HTTP1协议。 解决 FireFox 设置firefox的network.http.http2.enabled为禁用&#xff0c;这样就禁…