序列化成字符串不是真的字符串
将”[[1],[1,2]]“进行JSON.toJSONString()序列化仍然存在循环引用。
解决:JSON.toJSONString(reAnswerTypeList, SerializerFeature.DisableCircularReferenceDetect)
关于toString()误区,并不是都是返回字符串。Object类调用toString返回的就是地址
String s1 = "abc"; int[] arr1 = {1, 2, 3}; String[] arr2 = {"1", "2", "3"}; char[] arr3 = {'1', '2', '3'}; System.out.println(new Object().toString()); // 这里返回的不是"123"字符串,输出“java.lang.Object@3a63b47b”。Object类的toString()是返回地址 System.out.println(arr1.toString()); // 这里返回的不是"123"字符串,输出“[I@7b541799”。同new Object().toString() System.out.println(arr2.toString()); // 这里返回的不是"123"字符串,输出“[Ljava.lang.String;@4da88f66”。同new Object().toString() System.out.println(arr3.toString()); // 这里返回的不是"123"字符串,输出“[C@7b9ccc20”。同new Object().toString() System.out.println(new String(arr3)); // 这个才是返回字符串,输出“123”。
关于RestTemplate使用参数的问题
/* // 2024-01-24在154环境发现使用MultiValueMap反而失败 MultiValueMap<String,String> tempPostInfos= new LinkedMultiValueMap<>(); tempPostInfos.add("token",model.token); tempPostInfos.add("userID",model.userID); tempPostInfos.add("subjectID",model.subjectID); tempPostInfos.add("term",model.term); tempPostInfos.add("schoolID",model.schoolID); */ HttpEntity<Object> formEntity = new HttpEntity<>(JSON.toJSONString(model), httpHeaders); ResponseEntity<String> response = restTemplate.postForEntity(urlHeader, formEntity,String.class); String backInfo = null; if (response.getStatusCode() == HttpStatus.OK) { backInfo = response.getBody(); }
if(StringUtils.isNotBlank(backInfo)) {
ReturnResultReqModel<List<SystemsBySubjectIDModel>> tempStuPreScoreInfos = JSONObject.parseObject(backInfo,new TypeReference<ReturnResultReqModel<List<SystemsBySubjectIDModel>>>() {});
if(tempStuPreScoreInfos!=null&&tempStuPreScoreInfos.Data!=null) {
return tempSystemsBySubjectIDInfo;
}
}
使用MultiValueMap后台(.NET)接收到的格式为:
{ "token": [ "F397E507-AC79-42D4-A3E0-AFEF157F9F1A" ], "userID": [ "S417010275" ], "subjectID": [ "S1-English" ], "term": [ "2023-202402" ], "schoolID": [ "S-417" ]
使用JSON.toJSONString(model)后台(.NET)接收到的格式为:
{ "schoolID": "S-417", "subjectID": "S1-English", "term": "2023-202402", "token": "F397E507-AC79-42D4-A3E0-AFEF157F9F1A", "userID": "S417010275" }
关于C#语法糖(OrderBy/ThenByDescending)相关处理方式
LaterInfos = LaterInfos.OrderBy(t => t.TrainStage).ThenByDescending(t =>t.Integration).ThenByDescending(t => t.CRate).ToList();
import io.swagger.v3.oas.annotations.media.Schema; @Schema(description = "学生积分排名专用处理") public class UserRankModel{ @Schema(description = "用户ID") private String userID; @Schema(description = "训练阶段") private String trainStage; @Schema(description = "总积分") private Integer integration=0; @Schema(description = "正确率") private double cRate; public String getUserID() { return userID; } public void setUserID(String userID) { this.userID = userID; } public String getTrainStage() { return trainStage; } public void setTrainStage(String trainStage) { this.trainStage = trainStage; } public Integer getIntegration() { return integration; } public void setIntegration(Integer integration) { this.integration = integration; } public double getcRate() { return cRate; } public void setcRate(double cRate) { this.cRate = cRate; } }
// 排序
Comparator<UserRankModel> comparingHandel = Comparator.comparing(UserRankModel::getTrainStage).thenComparing(UserRankModel::getIntegration, Comparator.reverseOrder()).thenComparing(UserRankModel::getcRate, Comparator.reverseOrder());
数据集.sort(comparingHandel);
.NET与Java的时间转换为时间戳关系
/* * 获取时间戳差值 * */ public long getTicksServiceImpl(int SecondsNum) { /* * 注:不需要减去1970,因为C#里面的(new DateTime).Ticks为0 * DateTime dt1970 = new DateTime(1970, 1, 1, 8, 0, 0, 0); * return (DateTime.now().plusSeconds(-SecondsNum).getMillis() - dt1970.getMillis()) / 10000; * 但是,C#获取需要加上1970,C#代码例子如下: * DateTime dt1970 = new DateTime(1970, 1, 1, 8, 0, 0, 0); * long t = dt1970.Ticks + ticks * 10000; * return new DateTime(t); * */ return DateTime.now().plusSeconds(-SecondsNum).getMillis(); /* * 上面等价于: * long tempLongTicks = System.currentTimeMillis(); * return tempLongTicks-SecondsNum; * */ }
时间戳处理
// 时间和时间戳转换 System.out.println("时间戳:" + tempTimeStamp); tempTimeStamp = new Date().getTime(); System.out.println("时间戳1:" + tempTimeStamp); SimpleDateFormat tempSDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("时间戳->时间字符串:" + tempSDF.format(tempTimeStamp)); System.out.println("时间戳->时间:" + tempSDF.parse(tempSDF.format(tempTimeStamp))); DateTimeFormatter tempDTF = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); System.out.println("时间戳->时间字符串:" + tempDTF.print(tempTimeStamp)); System.out.println("时间戳->时间:" + tempDTF.parseDateTime(tempDTF.print(tempTimeStamp)));
备注:关于Date、Calendar、DateTime区别,可以查看这篇博客:java中的时间操作_java datetime-CSDN博客
关于java8的新属性Optional.ofNullable
ContentInfoModel tempContentInfo=new ContentInfoModel();
tempContentInfo.contentName="namejr";
tempContentInfo.contentPrice=1.0;
tempContentInfo.totleNum=10;
String tempContentName=Optional.ofNullable(tempContentInfo).map(t->t.contentName).orElse("namejr2");
Double tempContentPrice=Optional.ofNullable(tempContentInfo).map(t->t.contentPrice).orElse(2.0);
Integer tempTotleNum=Optional.ofNullable(tempContentInfo).map(t->t.totleNum).orElse(20);
System.out.println(tempContentName+"<=>"+tempContentPrice+"<=>"+tempTotleNum);
System.out.println("========================================");
tempContentInfo=null;
tempContentName=Optional.ofNullable(tempContentInfo).map(t->t.contentName).orElse("namejr2");
tempContentPrice=Optional.ofNullable(tempContentInfo).map(t->t.contentPrice).orElse(2.0);
tempTotleNum=Optional.ofNullable(tempContentInfo).map(t->t.totleNum).orElse(20);
System.out.println(tempContentName+"<=>"+tempContentPrice+"<=>"+tempTotleNum);
System.out.println("========================================");
输出:
namejr<=>1.0<=>10
========================================
namejr2<=>2.0<=>20
========================================
多重循环
System.out.println("开始执行多重循环"); firstBreakFlag: for (int i=0;i<10;i++){ for (int j=0;j<10;j++){ System.out.println("当前位置:"+i+","+j); if(i==5&&j==1){
// 跳出多重循环 continue firstBreakFlag; //break firstBreakFlag; } } } System.out.println("结束执行多重循环");
使用HttpServletRequest接收为空出理
public String postSpokenMarkResult(HttpServletRequest req) { String userID = null; // 学生学号 try { userID = req.getParameter("XH"); if(StringUtils.isBlank(userID)){ StringBuffer recvSBStr = new StringBuffer(); BufferedReader recvBRStr = req.getReader(); String tempLineInfo = null; while (null != (tempLineInfo = recvBRStr.readLine())) { recvSBStr.append(tempLineInfo); } Map<String,String> tempSpokenMark=JSONObject.parseObject(recvSBStr.toString(),new TypeReference<HashMap<String,String>>(){}); if(tempSpokenMark.containsKey("XH")){ userID = tempSpokenMark.get("XH"); } } ........ }
如果出现:如果出现unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidStatService
参照:博客后台 - 博客园 (cnblogs.com) 搜索"unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidStatService"
乱码/缓存空间不足
乱码:idea关于打包(客户端/后台)问题和乱码问题 - 闪电龟龟 - 博客园 (cnblogs.com)
缓存空间不足: 警告 [main] org.apache.catalina.webresources.Cache.getResource 无法将位于[/WEB-INF/classes/Audios/**/Question 88.mp3]的资源添加到Web应用程序[/*]的缓存中,因为在清除过期缓存条目后可用空间仍不足 - 请考虑增加缓存的最大空间。
在Tomcat部署路径下的./conf/context.xml配置文件的<Context>标签内添加如下内容: <Resources cachingAllowed="true" cacheMaxSize="100000" />
如果集成mybit后,没报错也也无法正常运行或者需要进行扫描关于mybit包dao包,请使用@MapperScans
详情区别请看:@MapperScan 和 @ComponentScan 区别_componentscan和mapperscan区别-CSDN博客
一些未正式在项目中使用的配置 或 spring boot项目中的配置笔记记录
#我们能配置的属性都来源于这个功能的properties类 spring.http.encoding.enabled=true #字符集 spring.http.encoding.charset=utf-8 #强制编码 请求响应必须为UTF8 spring.http.encoding.force=true
替换为servlet使用
# 我们能配置的属性都来源于这个功能的properties类 server.servlet.encoding.enabled=true # 字符集 server.servlet.encoding.charset=UTF-8 # 强制编码 请求响应必须为UTF8 server.servlet.encoding.force=true
#添加默认静态资源路径(通常不使用这个,如果存在拦截器/过滤器等处理,通常同样配置在重写WebMvcConfiguration里面,参照:@Configuration实现WebMvcConfigurer重写addResourceHandlers)
spring.web.resources.static-locations=
#配置文件传输
spring.servlet.multipart.enabled =true
spring.servlet.multipart.file-size-threshold =0
#单个数据的大小
spring.servlet.multipart.max-file-size = 10MB
#总数据的大小
spring.servlet.multipart.max-request-size=100MB
关于乱码问题,请参考:idea关于打包(客户端/后台)问题和乱码问题 - 闪电龟龟 - 博客园 (cnblogs.com)
异常:{"status":0,"data":null,"statusDescription":"Handler dispatch failed; nested exception is java.lang.StackOverflowError"}
笔记参照:FastJson稍微使用不当就会导致StackOverflow_fastjson2 死循环-CSDN博客、FastJson不成想还有个版本2啊:序列化大字符串报错 - 三国梦回 - 博客园
具体原因是框架自定的序列化解析导致的,如前端js结构上传,后端通过POST的@RequestBody方式接收模型,框架会自动调用转成模型,循环检索导致溢出。
解决方案:通过给转成的模型添加@JSONType(ignores = "jsonString")
package *.bean; import com.alibaba.fastjson.annotation.JSONType; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @Schema(description = "对象") @JSONType(ignores = "jsonString") public class TContent {public String a="";public dddd b;public List<aaaa> c; }
字符串/整型
线程安全:
字符串:StringBuffer
整型:AtomicInteger
非线程安全:
字符串:StringBuilder、String
整型:int、Integer