项目中遇到的错误及解决方案一

一、0 org/apache/http/ssl/TrustStrategy系统错误

该错误发生在调用第三方sdk时发生,经过排查发现该类存在与httpCore4.4以上版本中,其如下:

低于该版本的httpCore,则不存在该类,其如下:

解决方案:升级低版本的到4.4版本,同时升级对应的httpclientjar包

二、无法通过maven从本地仓库当中下载jar包

此错误发生多是由于存在.lastUpdated文件和.repositories文件。

解决方案:通过cmd命令打开命令行窗口,进入到仓库所在位置,然后执行下面两个命令删除上述文件,然后重新通过maven下载即可。

for /r %i in (*.lastUpdated) do del %i

for /r %i in (*.repositories) do del %i

三、使用oracle数据库时,导出,导入dmp文件

sql 复制代码
1、创建目录:create directory 文件名 as '路径'(该路径必须存在)(最大权限);
2、赋予权限: grant read,write on directory 文件名 to 用户名
   按表导出:
    expdp 用户名/密码@sid tables=表名 dumpfile=文件名.dmp directory=directory名称;
按用户导出:
    expdp 用户名/密码@sid schemas=用户名 dumpfile=data.dmp directory=directory名称;
全部导出:
    expdp 用户名/密码@sid directory=data_dump full=y dumpfile=data.dmp

导入:
    impdp c##zsk/password@helowin directory=data_dump dumpfile=文件名.dmp [remap_schema=c##zsk:c##test;]当用户名不一样时可以添加此参数
    
如果directory已经存在可通过SELECT * FROM SYS.DBA_DIRECTORIES 查询已经存在的directory的名称

四、文件下载时,文件名含有中文,导致乱码

perl 复制代码
1、对文件名进行编码并对编码后的"+"使用"%20"替换,此时编码后会将空格使用"+"替代,
因此会被认为文件名中有"+",因此需要替代,代码如下:
String fileName= URLEncoder.encode(fileName,"utf-8").replace("+","%20");
2、设置下载时的请求头"Content-Disposition":
response.setHeader("Content-Disposition","attachment;filename*=utf-8''"+fileName)

五、图片转base64

bash 复制代码
base64说明:base64要求把3个8位字节转成4个6位字节,之后在6位的前面补两个0,形成一个8位字节的形式,如果剩下的字符不足3个字节,则用0填充,输出字符"=",其支持的格式有 png,gif,jpg,bmp,ico格式;可通过工具类进行转换
其格式如下: data:image/类型;base,base64字符串

六、Pattern 正则表达式的运用

编译正则表达式(建议作用于全局): Pattern pattern = Pattern.compile("\d+");

获取匹配引擎对象: Matcher matcher = pattern.matcher("待匹配的字符串");

常用的方法: matcher.find():匹配下一个符合的对象,返回值为true/false matcher.start():匹配到的字符串的开始索引 matcher.end():匹配到的字符串的结束索引 matcher.group():返回匹配到的字符串 start(),end(),group()方法,在matcher.find()方法为true时生效

ini 复制代码
案例:在字符串中出现数字的前后添加$符
StringBuilder builder = new StringBuilder();
Pattern pattern = Pattern.compile("\\d+");
String str = "abc1cde23d";
Matcher matcher = pattern.matcher(str);
int lastIndex = 0;
while(matcher.find()){
    // 在前面添加
    builder.append(str,lastIndex,matcher.start()).append("$");
    // 在后面添加
    builder.append(matcher.group()).append("$");
    lastIndex = matcher.end();
}
builder.append(str,lastIndex,str.length());

七、关于在线预览word,pdf等文件

第一种解决方案:可以使用Aspose工具,以word为例

官网地址:www.aspose.com/

注意:该版本需要获取linces,免费版有限制

javascript 复制代码
1、引入所需jar包
  <dependency>
            <groupId>com.aspose.words</groupId>
            <artifactId>aspose-wrods</artifactId>
            <version>21.11</version>
        </dependency>
2、编写代码将word转为pdf:
            FileInputStream fileInputStream = new    FileInputStream("C:\\Users\\aifeng\\Desktop\\文件名");
        Document document = new Document(fileInputStream);
        res.setContentType("application/pdf");
        document.save(res.getOutputStream(), SaveFormat.PDF);

第二种:使用KKFileView开源项目:

文档地址:kkview.cn/zh-cn/index...

gitee地址:gitee.com/kekingcn/fi...

typescript 复制代码
使用方式:
前提:
1、安装jdk1.8+
2、安装LibreOffice或OpenOffice
3、环境安装好以后,下载官方提供的安装包,将其安装并启动即可

使用:调用浏览器打开预览接口即可
3版本以上用法:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/js-base64@3.6.0/base64.min.js"></script>
var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(previewUrl)));
2版本及以下用法:
var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(previewUrl));

第三种:使用文档转换工具jodConverter和(LibreOffice或OpenOffice)

项目地址:github.com/jodconverte... 使用步骤:

typescript 复制代码
1、引入依赖的jar包:
<!--将microsoft office转换为pdf它依赖 OpenOffice或者是-->
<dependency>
    <groupId>org.jodconverter</groupId>
    <artifactId>jodconverter-core</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.jodconverter</groupId>
    <artifactId>jodconverter-local</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.jodconverter</groupId>
    <artifactId>jodconverter-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>org.libreoffice</groupId>
    <artifactId>ridl</artifactId>
    <version>5.4.2</version>
</dependency>

2、配置一些基本属性
jodconverter:
  local:
    #可以控制是启用jodconverter自带的配置类,false关闭
    enabled: false
    office-home: D:\\LibreOffice
    #可以指定多个端口,一个端口表示一个进程
    port-numbers: 2003
    max-tasks-per-process: 100
    process-timeout: 120000

3、编写配置类
@Component
@Slf4j
public class OfficeConverterConfig {

    @Value("${jodconverter.local.office-home}")
    private String officeHome;

    @Value("${jodconverter.local.port-numbers}")
    private String portNumbers;

    @Value("${jodconverter.local.max-tasks-per-process}")
    private int taskProcessNum;

    @Value("${jodconverter.local.process-timeout}")
    private Long processTimeout;

    private OfficeManager officeManager;

    @PostConstruct
    public OfficeManager officeManager() {
        // 多个端口处理
        String[] portsString = portNumbers.split(",");
        int[] ports = Arrays.stream(portsString).mapToInt(Integer::parseInt).toArray();
        // 系统判断
        String os = System.getProperty("os.name").toLowerCase();

        officeManager = LocalOfficeManager.builder()
                .officeHome(os.contains("windows") ? officeHome : "linuxHome")
                .portNumbers(ports)
                .processTimeout(processTimeout)
                .maxTasksPerProcess(taskProcessNum)
                .install()
                .build();
        try {
            officeManager.start();
            InstalledOfficeManagerHolder.setInstance(officeManager);
            log.info("office进程启动成功");
        } catch (OfficeException e) {
            log.error("启动office组件失败");
            throw new RuntimeException(e);
        }
        return officeManager;
    }

    @PreDestroy
    public void destroyOfficeManager() {
        if (null != officeManager && officeManager.isRunning()) {
            log.info("终止office进程");
            OfficeUtils.stopQuietly(officeManager);
        }
    }

    @Bean
    public DocumentConverter documentConverter() {
        LocalConverter converter = LocalConverter.builder()
                .officeManager(officeManager)
                .build();
        return converter;
    }
    
4、基本使用:
    @Autowired
    private DocumentConverter documentConverter;

    @GetMapping("/preview")
    public void t1() throws IOException, OfficeException {
        FileInputStream fis = new FileInputStream("C:\\Apose操作DOC,pdf等.doc");
        FileOutputStream outputStream = new FileOutputStream("C:\1.pdf");
        documentConverter.convert(fis)
                .as(DefaultDocumentFormatRegistry.DOC)
                .to(outputStream)
                .as(DefaultDocumentFormatRegistry.PDF)
                .execute();
    }

八、如何生成树形结构的数据

第一种:递归

实现如下:

scss 复制代码
 @GetMapping("/tree1")
    public List<TreeNode> treeSelect(){
        //获取数据
        List<TreeNode> maps = mapList();
        // 收集顶层节点
        List<TreeNode> pList = maps.stream().filter(item -> "0".equals(item.getParentId()))
                .collect(Collectors.toList());
        for (TreeNode treeNode : pList) {
            //遍历子节点
            getChildren(treeNode,maps);
        }
        return pList;
   }
   private void getChildren(TreeNode treeNode, List<TreeNode> maps) {
        List<TreeNode> pList = maps.stream().filter(item -> treeNode.getId().equals(item.getParentId()))
                .collect(Collectors.toList());
        treeNode.setChildren(pList);

        for (TreeNode node : pList) {
            getChildren(node,maps);
        }
    }

第二种:使用Stream流

scss 复制代码
 public List<TreeNode> treeSelect2(){
        List<TreeNode> maps = mapList();
        //根据父ID进行分组,父ID相同的分在一组
        Map<String, List<TreeNode>> map = maps.parallelStream().collect(Collectors.groupingBy(TreeNode::getParentId));

        //遍历所有节点,设置其子节点
        maps.forEach(item->item.setChildren(map.get(item.getId())));
        // 筛选经济节点
        return maps.stream().filter(item->"0".equals(item.getParentId())).collect(Collectors.toList());
    }

第三种:使用hutool的工具类

ini 复制代码
// 简单应用
 public List<Tree<String>> treeSelect3(){
        List<cn.hutool.core.lang.tree.TreeNode<String>> treeNodes = mapList2();
        List<Tree<String>> build = TreeUtil.build(treeNodes, "0");
        return build;
    }
    
// 使用hutool的工具树类,并自定义TreeNode和自定义返回值名称
public List<Tree<String>> treeSelect5(){
    List<TreeNode> treeNodes = mapList();
    TreeNodeConfig nodeConfig = new TreeNodeConfig();
    //自定义显示值
    nodeConfig.setNameKey("label");

    return TreeUtil.build(treeNodes, "0", nodeConfig,(treeNode, tree) -> {
        tree.setId(treeNode.getId());
        tree.setParentId(treeNode.getParentId());
        tree.setName(treeNode.getLabel());
    });
}

九、在completableFuture中抛出自定义异常没有被全局异常捕获

当CompletableFuture中的代码报错时,会将其包装成CompletableFuture对象,并抛出 CompletionException异常对象。此时可以通过exceptionally或者handle进一步处理异常,如果在此抛出了自定义异常,并且使用了allof().join()方法时,则最终抛出的是CompletionException异常对象,并不是自定义异常,因此若想全局异常捕获,需要定义其对应的异常处理器

十、全局异常处理器无法捕获在Filter中抛出的自定义异常

@ControllerAdvice注解只能捕获在controller层抛出的异常;当在Filter中抛出异常时,此时还没有到controller层,因此不会被捕获。使用HandlerExceptionResolver异常类进行包装可以解决。

HandlerExceptionResolver:是springweb MVC最简单,最常用的异常处理器。会对@ControllerAdvice和ExceptionHandler注解标注的异常处理器进行缓存。在寻找对应的异常处理器时,HandlerExceptionResolver会根据异常处理对象寻找合适的异常处理器方法

相关推荐
zquwei12 分钟前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
TT哇18 分钟前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
dessler33 分钟前
Docker-run命令详细讲解
linux·运维·后端·docker
火烧屁屁啦41 分钟前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
w_31234541 小时前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
岁岁岁平安1 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA1 小时前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_19284999061 小时前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
张国荣家的弟弟1 小时前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi