一、文件路径问题大集合

1、System.getProperty("user.dir")    #获取当前项目文件夹在磁盘上的绝对路径(java命令执行的地方)

2、File tmpFile = new File("/tmp/tomcat");   #这样会在当前项目所在磁盘的根路径下创建该文件夹

3、File tmpFile = new File("tmp/tomcat");   #这样就是在当前项目的根目录下创建该文件夹 。。默认是从当前项目根目录下开始找

4、File tmpFile = new File("../tmp/tomcat");   #与项目同级创建该文件夹

5、String fileAbsolutePath = file.getCanonicalPath();   #获取解析后的文件(夹)的绝对路径,如D:\java\companyProject\zt_slimming\..\headImg =》D:\java\companyProject\headImg

classpath里面时

this.getClass().getClassLoader().getResources("word/xunhuan.docx").toURI().getPath();

this.getClass().getClassLoader().getResourceAsStream("word/xunhuan.docx");

this.getClass().getResources("/word/xunhuan.docx").toURI().getPath();

this.getClass().getResourceAsStream("/word/xunhuan.docx");

classLoader默认就是从当前类路径下classpath/ 开始加载,所以不用加 /

class 默认是从当前类的位置开始加载,加上/ 就代表从类路径下开始加载。

斜杠(/)和反斜杠(\)

java中一般用斜杠 /

window的文件路径为 \ ,因为需要转义,所以要 \\ 。但通过 / 同样可以定位到文件。

Linux的文件路径为 /

数据库中存储是就存 /

二、路径中带有中文或空格时会提示找不到资源

如:从类路径下获取某个文件的文件路径,提示找不到资源:

String filePath = this.getClass().getClassLoader().getResource("word/xunhuan.docx").getPath();

解决:加上toURI()方法即可

String filePath = this.getClass().getClassLoader().getResource("word/xunhuan.docx").toURI().getPath();

PS:直接获取对应的流时,路径中带有中文或空格就没有关系了。

三、springBoot项目jar包转换成war包,并部署到tomcat服务器上

为什么要转成war包?

war包更像是一个大的应用资源容器,而jar包更像是一个功能单元,打成war包后就能随意的访问war包内的任意资源,但jar包却不可以。

步骤:两大步

1、修改pom.xml文件

1.1 packaging改成war包

<groupId>com.jyf</groupId>
<artifactId>online_exam</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>online_exam</name>
<!--1、修改打成war包,默认为jar包-->
<packaging>war</packaging>
<description>Demo project for Spring Boot</description>

1.2 排除内置的tomcat服务器

<!--推荐:2、添加tomcat的依赖,可以自动排除掉内置的tomcat,并提供javax.servlet-api-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope>//只在编译时有效,打包运行时就是用服务器的环境了
</dependency>

或者在spring-boot-starter-web中排除tomcat的依赖,并额外添加javax.servlet-api(provided)

1.3添加项目名(可选)

<!--指定当前项目的上下文名称(如果需要的话)项目改成war包后,springBoot配置中配置的端口号,contextPath就无效了,如果需要指定,可以在这里修改项目名,在tomcat的配置文件中修改端口号 -->
<build>
<!--<finalName>/online_exam</finalName>-->
</build>

2、修改启动类

继承SpringBootServletInitializer,并重写其configure方法

@SpringBootApplication
@MapperScan(basePackages = "com.zhaotai.mapper")
public class OnlineExamApplication extends SpringBootServletInitializer {public static void main(String[] args) {SpringApplication.run(OnlineExamApplication.class, args);}@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {return builder.sources(OnlineExamApplication.class);}
}

之后使用maven clean、compile、 package 打包即可

3、部署到tomcat上并访问(Tomcat8.5及以上版本)

由于原来访问时,是直接从端口号开始的没有项目名,在tomcat中也想这么做的话,有两种方式:

方式一:默认的ROOT目录

webapps下新建ROOT文件夹:将war包中的文件夹放到ROOT下即可。

方式二:虚拟路径映射

server.xml文件中的<Host></Host>节点中添加

<Context path="" docBase="F:\temp" reloadable="false" />

path:代表项目名。此时 如 localhost:8080 这样就可以访问。

docBase:代表项目的绝对路径。如:F:\temp\sixBookStore

注意:如果是直接放到webapps下,默认是根据项目的文件名进行访问的。

此时后台路径的 “/” 就代表当前项目的根目录,但前台的 “/”代表当前端口号下,所有就访问不了后台,所以要在访问路径中加上当前项目的contextPath。

如:使用Thymeleaf的内联表达式 var path = "[[${#request.getContextPath()}]]";

后台整个 ServletContextListener 在服务器启动时在application域中添加代表当前项目根目录的一个变量,前台:var path = "${application.myContextPath}";

四、接收和返回时间格式的处理

1、Date类型接收格式

首先,java Date类型默认的接收时间格式为 xxxx/xx/xx xx:xx:xx,但前端的日期插件和数据库中默认时间格式都为 xxxx-xx-xx xx:xx:xx。

所以为了后台能正确接收需要

方式一、使用@DateTimeFormat注解(针对键值对格式)

或@JsonFormat注解(针对json字符串转java对象时的转化),局部的较灵活

方式二、配置文件中 spring.mvc.date-format=yyyy-MM-dd HH:mm:ss 全局的,不太灵活

例如:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//接收时

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")//接收时和返回时

private Date createTime;//创建时间

2、Date类型返回格式

jackson方式:

springBoot默认使用Jackson作为HttpMessageConverter(消息转换器),此时直接在实体类的属性上使用@JsonFormat注解,即可按照指定的时间格式返回,注意要添加时区 timezone="GMT+8"。

局部的:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")

yml文件中全局配置:

spring:

#配置统一的日期返回格式

jackson:

time-zone: GMT+8

date-format: yyyy-MM-dd HH:mm:ss

注意:若全局和和局部的方式都存在的话,采用就近原则:局部的会覆盖全局的。

fastJson方式:

使用fastJson 的@JsonField注解:@JSONField(format = "yyyy-MM-dd HH:mm:ss")

此时需要注入FastJson的转换器来替换掉默认的
@Bean
public HttpMessageConverters httpMessageConverter(){FastJsonHttpMessageConverter fastJson = new FastJsonHttpMessageConverter();return new HttpMessageConverters(fastJson);

但是FastJson默认所有为null的属性不参与序列化,所以返回结果中将没有这些属性。

解决: 在所有可能为null的属性上添加 @JsonFiled注解的一个属性即可:@JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue)

五、上传文件大小限制(Tomcat服务器)

tomcat默认的上传文件的大小为2MB,

<!--maxPostSize="0":对于post请求的数据不限制大小,解决文件上传大小限制问题,默认为2MB。

connectionTimeout="20000":20秒的有效连接,可以设置的大一点来解决大文件上传 -->

<Connector connectionTimeout="20000"

maxPostSize="0"

port="8080"

protocol="HTTP/1.1"

redirectPort="8443"/>

springboot默认的上传的单个文件大小为1MB,一次请求的多个文件大小为10MB,

参看源码配置类 MultipartProperties

springBoot中配置文件上传大小:

springboot2.x

spring.servlet.multipart.max-file-size=5MB   #单个文件的最大大小限制

spring.servlet.multipart.max-request-size=30MB  #单个请求中多个文件的最大大小限制

springboot1.x

spring.http.multipart.max-file-size=5MB

spring.http.multipart.max-request-size=30MB

六、上传文件临时目录问题(Tomcat服务器)

文件上传会先上传到OS的临时目录中,在同步到设定目录中。

System.getProperty("java.io.tmpdir"); 当前操作系统默认的临时文件存放位置。

window下:C:\Users\ADMINI~1\AppData\Local\Temp\ 环境变量->用户变量的TEMP变量值

Linux下:/tmp

如果是用外部的servlet容器,如Tomcat,则会在tomcat启动的时候在catalina.sh里面,将tomcat的临时目录temp的路径位置赋值给OS的临时目录,这样上传的资源就会到tomcat的temp目录下,在同步到设定的目录中。当tomcat重启时会清空temp的内容。

如果是用内嵌的servlet容器,如springBoot项目,当项目启动时,会创建一个临时目录用来存放上传的文件资源(临时目录就是OS的临时目录),当部署到Linux下,Linux会每隔10天自动清理不使用的临时目录,就导致文件上传不上去。

解决:指定一个目录当做临时目录,这样就不会被Linux清理掉了

@Bean
public MultipartConfigElement multipartConfigElement() {MultipartConfigFactory factory = new MultipartConfigFactory();String location = System.getProperty("user.dir") + "/../tempUpload";//与项目同级创建该文件夹File tmpFile = new File(location);if (!tmpFile.exists()) {tmpFile.mkdirs();}factory.setLocation(location);return factory.createMultipartConfig();
}

七、系统控制台打印出有颜色的字符

如:

System.out.println("\033[31;44;0m" + "我滴个颜色" + "\033[31;44;0m");

System.out.println("\033[33;0m"+"异常为:"+"\033[33;0m");

格式:

前缀:\033[ 中间:颜色;背景色;样式 后缀m

中间的任意一个不写默认为不加该样式

范围:颜色表达式后面的所有,除非遇到另一个颜色表达式

颜色1

背景色

样式

30  白色

40-47颜色和颜色1一样

0  空样式

31  红色

1  粗体

32  绿色

4  下划线

33  黄色

7  反色

34  蓝色

35  紫色

36  浅蓝

37  灰色

八、配置多个springBoot项目在Run Dashboard中运行

idea中不像eclipse中有workspace和project的概念,取而代之的是project和module的概念。当我们在同一个project下建立多个module时,比如我们要做一个springBoot的maven多模块项目,默认情况下idea是会自动检测多个springBoot项目,当同时启动第二个springBoot项目时会询问你是否在Run Dashboard(顾名思义叫运行仪表盘,可以方便管理多个项目的运行和停止等操作)中运行。如果前几个module都是在Run Dashboard中运行,新建的module不在Run Dashboard中运行了,可以是idea的run configurations没配置好:

通过Run-》Edit Configurations 打开运行配置,可以看到

新创建的应用跑到Application中去了,所以idea不会把它和其他项目归为一类,所以不会再仪表盘中显示。

解决:

点击绿加号-》选择springBoot-》修改新添加的配置的Name和Main class 即可,然后就可以在Run Dashboard中看到刚才新添加的项目了。

九、异常:getReader() has already been called for this request

1、起因

我在利用filter做接口鉴权操作,在filter中获取请求体中的json字符串,然后做签名比对,如下

 /*** 获取请求体中的json字符串* @param request* @return* @throws IOException*/private String getJsonStr(HttpServletRequest request) throws IOException {BufferedReader reader = request.getReader();StringBuilder sb = new StringBuilder();String line = null;line = reader.readLine();while (line != null){sb.append(line);line = reader.readLine();}return sb.toString().replaceAll("\\s","").replaceAll(BigTreeConstant.replaceStr,"");}

等filter通过之后,在controller层获取json字符串:

    @PostMapping("/notify/result")public RestResult resultNotice(HttpServletRequest request,@RequestBody
Map<String,Object> map) {//do something}

2、现象

filter通过后,直接报了如下异常:

getReader() has already been called for this request

意思是getReader()方法已经被这个request调用过了。在网上查了下资料,说同一个请求HttpServletRequest对象的getReader()或getInputStream()只能被调用一次,且只能有一个被调用。 分析了一下,我在filter中确实用了request.getReader(),猜测可能springMVC在应用@RequestBody注解时,也调用了request.getReader()或getInputStream()获取请求体的流,导致了报错。

3、解决

怎么办呢?网上有说用aop代替filter的,有说重写getInputStream()和getRead()方法,暂存数据的。但我想不会这么麻烦吧!突然想到了springMVC的调用链路和request对象的生命周期。既然filter调用完最终也会调用controller方法,而且filter中的httpServletRequest对象和controller中的隐式入参httpServletRequest对象是一个,那我在filter的request对象中放入数据,在controller的request对象中获取数据不就行了吗?

结果一试还真可以,以下是代码部分:

    //filter中 @Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {request.setAttribute("data",jsonStrData);
}//controller层@PostMapping("/notify/result")public RestResult ResultNotice(HttpServletRequest request) {String jsonStr = String.valueOf(request.getAttribute("data"));
}

多说一句,扎实的基础很重要。

十、mysql tinyint(1) 默认当做boolean来处理

1、背景:

再用mybatis做关联查询时,将数据库中一个tinyint(1) 的字段传给了关联的sql语句,如下:

<collection property="deptList" ofType="xxx" column="{sortType=sort_type}" select="listxxx"/><select id="listxxx" resultMap="employeeResultMap">select * from employeewhere sortType = #{sortType}
</select>

#{sortType} 原本的值是1 或者 2,数据库中用了tinyint(1)类型存储,结果控制台打印发现

#{sortType}的值为总是为true,导致了关联查询结果不理想。

2、原因:

mysql将tinyint(1)类型的值,默认当成true和false来处理,0是false,其余的123456789都是true,就导致映射成java实体类属性时变成了true。

3、解决:

  • 不用tinyint(1),使用tinyint(n>=2),或者使用tinyint不指定长度,默认是4。
  • 在jdbc连接的url属性值中加上 tinyInt1isBit=false

十一、mybatisPlus分页时利用Page对象排序失效

1、现象:

使用mybatisPlus的Page参数对象分页排序时,给page对象的orders属性设置了排序字段,但是实际并没有生成排序的sql,代码如下:

final List<OrderItem> orderItems = Collections.singletonList(OrderItem.asc("createTime"));
page.setOrders(orderItems);
return this.page(page);

2、原因:

猜测时mybatisPlus版本问题,所以从3.4.1 降到了3.3.2,再次执行同样的代码,发现生成了排序的sql。

3、解决:

将mybatisPlus的版本降到3.3.2或以下即可。

待续...

也可以将你的其他问题以及验证过得解决方式发布到这篇文章中来,评论区留言即可,看到后我会合并进来的...

java开发中遇到的问题及解决方法相关推荐

  1. java开发中遇到的问题及解决方法(持续更新)

    java开发中遇到的问题及解决方法(持续更新) 参考文章: (1)java开发中遇到的问题及解决方法(持续更新) (2)https://www.cnblogs.com/LiuYanYGZ/p/6112 ...

  2. [原]java开发中遇到的问题及解决方法(持续更新)

    工作中,以C/C++开发为主,难免与其他服务和Web进行交换,Java开发必不可少,又不想动用Eclipse大家伙,只能自己动手编写脚本进行Java代码的编译和运行,期间遇到的一些问题,记录下来供自己 ...

  3. 微信小程序在开发中遇到的问题与解决方法

    微信小程序在开发中遇到的问题与解决方法 参考文章: (1)微信小程序在开发中遇到的问题与解决方法 (2)https://www.cnblogs.com/zjjDaily/p/8032142.html ...

  4. Android实际开发中的bug总结与解决方法(一)

    Android实际开发中的bug总结与解决方法(一) 参考文章: (1)Android实际开发中的bug总结与解决方法(一) (2)https://www.cnblogs.com/ywq-come/p ...

  5. 前端开发中遇到的问题及解决方法

    前端开发中遇到的问题及解决方法 1,何为MVVM? view层: 视觉层:在前端开发中,通常是DOM层:主要作用是给用户展示各种信息: Model层: 数据层:数据可能是我们固定的死数据,更多的是来自 ...

  6. 小米首页实践开发中遇到的问题及解决方法

    小米首页实践开发中遇到的问题及解决方法 1.菜单栏的指向小三角问题 解决方法:使用矩形边框绘制三角形,用CSS设置矩形内容为空.边框设置一定的宽度(三角形的高),并且设置一个方向的边框颜色,其他方向颜 ...

  7. java开发中遇到的问题_java开发中遇到的问题及解决方法(持续更新)

    摘自 http://blog.csdn.net/pony12/article/details/38456261 工作中,以C/C++开发为主,难免与其他服务和Web进行交换,Java开发必不可少,又不 ...

  8. android应用开发中收集的异常日志解决方法记录

    这里主要是列出开发中收集的一些错误日志,以及解决方案,仅供参考,也有待解决的问题 1, ListView 中出现java.lang.IndexOutOfBoundsException: Invalid ...

  9. 浅谈Excel开发:九 Excel 开发中遇到的常见问题及解决方法

    Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家有所帮助. 一 插件调试不了以及错误导致崩溃的问题 在开发机器上,有时可 ...

最新文章

  1. 实时计字数提醒的文本框
  2. C++ 值传递、指针传递、引用传递
  3. 更新maven一直在更新_海尔电视更新应用一直闪退?详细解决方法来了!
  4. P1115 最大子段和
  5. ubuntu下安装并配置VIM编辑器
  6. [蓝桥杯][基础练习VIP]报时助手
  7. P3694-邦邦的大合唱站队【状压dp】
  8. MachineLearning(4)-核函数与再生核希尔伯特空间
  9. 5-13自定义sink到MySQL.
  10. 递增序列(迭代加深)
  11. c#图解教程和c#高级编程电子书链接
  12. cefsharp 添加html,winform+cefSharp实现窗体加载浏览器
  13. 前端JQuery插件distpicker.js的部分操作使用
  14. android 考勤界面,一种android终端实时考勤记录统计展现方法和装置与流程
  15. The Matrix
  16. Python 爬虫模拟器
  17. java将string转为json_java 怎么将string转为json数据
  18. html星座代码,各星座详细页面.html
  19. fmm3d在windows环境中的编译使用过程
  20. 线性代数-克莱姆法则

热门文章

  1. (附源码)Python《C语言程序设计》课程案例库研究 毕业设计030946
  2. 李开复给女儿的信:你该如何度过大学生涯
  3. 同等学力复习备考の有了它,妈妈级考生也能通过同等学力考试!
  4. [element-ui] 报错 custom validator check failed for prop “percentage“
  5. autodock windows安装对接使用、vina安装;openbabel安装使用
  6. CAD浏览模式与绘图模式、CAD如何一次性打印上百张图纸
  7. 2021-11-22 WPF上位机 94-Modbus通信数据交换问题
  8. TX1刷机+安装YOLOv3
  9. 《见识》:你能走多远,取决于见识
  10. 如何在服务器管理器删除服务器,Windows 系统如何在服务器管理器删除服务器