学习目标:
掌握实战项目各种开发过程
学习内容:
某某项目的源码实操,记录常用的“姿势”,
例如:
- 架构设计
- 掌握 Java 基本语法
- 分析各种常用的类以及方法
- 掌握开发必备技巧
- 分析源码
学习时间:
`7.16+7.17
项目涉及的接口
MultipartFile
MultipartFile 是一个接口,定义了处理上传文件的操作。该接口扩展了 InputStreamSource 接口,表示上传文件可以作为 InputStream 来访问。
接口定义了多个方法来获取上传文件的不同属性,包括文件名、大小、内容类型等。一般来说,在处理上传文件时,应首先创建一个 MultipartFile 对象,然后使用该对象的方法来获取文件属性并进行后续处理。
public interface MultipartFile extends InputStreamSource
InputStreamSource
定义了获取输入流的操作。该接口只有一个方法 getInputStream(),该方法返回一个 InputStream 类型的对象,用于读取数据。
InputStream
InputStream 是一个抽象类,在 Java I/O 库中用于从输入流中读取数据。
该类提供了多个方法来读取不同类型的数据,例如 read() 方法用于读取单个字节,
read(byte[]) 方法用于读取一定长度的字节数组,
skip() 方法用于跳过指定数量的字节等。同时,InputStream 类还实现了 Closeable 接口,因此可以使用 close() 方法关闭输入流并释放相关资源。
Throwable
在 Java 中,所有的异常类都继承自 Throwable 类,包括 Error、Exception 和自定义异常类等。
Throwable 类定义了一些基本的异常属性和方法,例如异常消息、异常堆栈轨迹、打印异常信息等。使用 Throwable 类可以方便地创建和处理异常,帮助程序员更好地理解和调试程序。
Throwable 类还提供了一些有用的方法,例如 getMessage() 方法用于获取异常消息,printStackTrace() 方法用于打印异常堆栈信息等
Future
Future 是 Java 并发编程中的一个接口,表示一个异步计算的结果。当一个线程需要执行一个耗时的操作时,可以通过 Future 来获取该操作的结果,并在需要的时候中断该操作。
boolean cancel(boolean mayInterruptIfRunning):尝试取消该异步计算。如果该计算已经完成或已经被取消,则该方法返回 false;如果该计算正在执行,并且 mayInterruptIfRunning 参数为 true,则该计算会被中断,并返回 true;否则该计算不会被中断,并返回 false。
boolean isCancelled():返回该异步计算是否已经被取消。
boolean isDone():返回该异步计算是否已经完成(无论是正常完成还是被取消)。
V get():返回该异步计算的结果,如果该计算还未完成,则该方法会阻塞当前线程直到计算完成。
V get(long timeout, TimeUnit unit):返回该异步计算的结果,如果该计算还未完成,则该方法会阻塞当前线程直到计算完成或者等待时间超过 timeout 参数所指定的时间。
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
//Executors.newSingleThreadExecutor() 方法创建一个单线程的线程池 executor,用于执行异步计算。
Future<String> future = executor.submit(() -> {
//executor.submit() 方法提交一个异步计算,该计算会在 Callable 对象中执行。
Thread.sleep(3000);
// lambda 表达式来创建一个 Callable 对象,该对象会休眠 3 秒钟,然后返回字符串 "Hello, Future!"。
return "Hello, Future!";
});
try {
String result = future.get(5, TimeUnit.SECONDS);
//future.get() 方法获取异步计算的结果
System.out.println(result);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
} finally {
future.cancel(true);
// future.cancel() 方法尝试取消异步计算
executor.shutdown();
//executor.shutdown() 方法关闭线程池
}
}
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<String> task = new Callable<String>() {
public String call() throws Exception {
// 在这里进行图片 URL 的获取操作
return "https://example.com/image.jpg";
}
};
Future<String> future = executor.submit(task);
// 在需要使用图片 URL 的地方调用 future.get() 方法
String imageUrl = future.get();
System.out.println(imageUrl);
项目涉及的注解类
@TableName(autoResultMap = true)
MyBatis-Plus 框架提供的一个注解,用于标注实体类对应的数据表名。
其中 autoResultMap 参数表示是否自动创建结果映射。如果设置为 true,则 MyBatis-Plus 会自动创建结果映射,否则需要手动创建。
当 autoResultMap 参数设置为 true 时,MyBatis-Plus 会自动根据实体类中的字段和数据表中的列名进行映射,从而提供更加便捷的 ORM 操作。
例如,如果实体类中有一个字段名为 user_name,而数据表中的列名为 user_name,则 MyBatis-Plus 会自动将这两个字段进行映射,从而在查询、更新等操作中可以直接使用实体类中的字段名,而无需手动指定列名。
这是没有使用这个注解
import com.baomidou.mybatisplus.annotation.TableField;
public class User {
@TableField(value = "id")
private Long id;
@TableField(value = "name")
private String name;
@TableField(value = "age")
private Integer age;
// getters and setters
}
这是使用了这个注解:
import com.baomidou.mybatisplus.annotation.TableName;
@TableName(value = "user", autoResultMap = true)
public class User {
private Long id;
private String name;
private Integer age;
}
@TableField(typeHandler = JacksonTypeHandler.class)
MyBatis-Plus 框架提供的一个注解,用于标注实体类中的字段在数据表中对应的列名和属性。其中 typeHandler 参数用于指定该字段在序列化和反序列化时所使用的类型处理器。
JacksonTypeHandler 类型处理器是 MyBatis-Plus 框架提供的一个类型处理器,它可以将 Java 对象和 JSON 字符串之间进行转换。
当我们使用该注解标记一个字段时,MyBatis-Plus 会自动将该字段的值序列化成 JSON 字符串,并将其保存到数据库中;当我们从数据库中读取该字段的值时,MyBatis-Plus 会自动将 JSON 字符串反序列化成 Java 对象,并返回给我们。
项目涉及的方法
上传文件
一般使用oss(Object Storage Service),写一个接口(里边写上要的方法,比如上传(参数为string、MultipartFile)等)
replace()(replace() 方法是区分大小写的)
String 类的 replace() 方法。该方法接收两个参数,第一个参数是要被替换的字符串,第二个参数是要替换成的字符串。该方法会在字符串中查找所有匹配的子串,并将其替换成指定的字符串。
String htmlContent = "<img src=\"https://example.com/old-image.jpg\" alt=\"Image\">";
String oldUrl = "https://example.com/old-image.jpg";
String imageUrl = "https://example.com/new-image.jpg";
htmlContent = htmlContent.replace(oldUrl, imageUrl);
System.out.println(htmlContent);
replaceAll()
如果要进行不区分大小写的替换操作,可以使用 replaceAll() 方法,并提供一个正则表达式作为第一个参数。
indexOf()
如果indexOf()返回值不是-1,则表示子字符串被找到
package java.lang;
UUID.fastUUID()
该方法返回一个随机生成的 UUID 对象,它是一个128位的唯一标识符。
与传统的 UUID.randomUUID() 方法相比,fastUUID() 方法使用了一些优化技术来提高生成速度。具体来说,fastUUID() 方法使用了一个特殊的算法来生成 UUID,这个算法的性能比传统的随机数生成器更好,因此可以更快地生成 UUID。
package cn.hutool.core.lang;
DateUtil.today()
该方法返回当前日期的字符串表示形式
package cn.hutool.core.date;
file.getOriginalFilename()
目的是获取上传文件的原始文件名。这里的 file 可能是一个包含上传文件信息的对象,通常是 org.springframework.web.multipart.MultipartFile 类的实例。
通常需要获取原始文件名以进行后续操作,例如检查文件类型、重命名文件等。
BeanUtils.copyProperties()
该方法会将源 JavaBean 对象中的属性值复制到目标 JavaBean 对象中,从而实现属性值的拷贝。
只会复制两个 JavaBean 对象中属性名相同、类型相同且可访问(即具有 getter 和 setter 方法)的属性值。
如果源 JavaBean 对象中的属性值为 null,则目标 JavaBean 对象中的属性值也会被设置为 null;
如果源 JavaBean 对象中的属性值不为 null,则目标 JavaBean 对象中的属性值会被覆盖为源 JavaBean 对象中的属性值。
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, (Class)null, (String[])null);
}
StringEscapeUtils.unescapeHtml4()
是 Apache Commons Lang 包提供的一个方法,用于将 HTML 转义字符转换回对应的字符。
import org.apache.commons.text.StringEscapeUtils;
public class HtmlUnescapeExample {
public static void main(String[] args) {
String htmlString = "<div>Hello, &lt;World&gt;!</div>";
String unescapedString = StringEscapeUtils.unescapeHtml4(htmlString);
System.out.println(unescapedString);
//可以看到输出结果为 <div>Hello, <World>!</div>,表明我们成功地将 HTML 转义字符转换回了对应的字符。
}
}
正则表达式
Pattern.compile() +p.matcher() + m.find() + m.group()
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ImgTagRegexExample {
public static void main(String[] args) {
String content = "<div><img src=\"image.jpg\" alt=\"A beautiful image\"></div>"
+ "<p><img src=\"picture.png\" alt=\"Another great picture\"></p>";
String IMG_PATTERN = "<img\\s+[^>]*src\\s*=\\s*['\"]([^'\"]*)['\"][^>]*>";
Pattern p = Pattern.compile(IMG_PATTERN, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(content);
while (m.find()) {
String imgTag = m.group();
System.out.println(imgTag);
}
}
}
Pattern.compile() 方法创建一个 Pattern 对象 p,表示一个用于匹配的正则表达式。
Pattern pattern = Pattern.compile("\\w+"); // 匹配一个或多个单词字符
p.matcher() 方法创建一个 Matcher 对象 m,表示对 content 进行匹配操作。
String input = "The quick brown fox jumps over the lazy dog.";
Pattern pattern = Pattern.compile("\\w+"); // 匹配一个或多个单词字符
Matcher matcher = pattern.matcher(input);
m.find() 是 Matcher 类中的一个方法,用于在输入字符串中查找下一个匹配的子串。**该方法可以用于对输入字符串进行多次匹配操作,**每次匹配会在上一次匹配的结束位置之后开始。如果找到了符合要求的子串,则该方法返回 true;否则返回 false。
m.group() 是 Matcher 类中的一个方法,用于返回上一次匹配操作中匹配的子串。该方法可以用于获取正则表达式匹配操作中,匹配成功的子串。如果在上一次匹配操作中没有找到匹配的子串,则该方法会抛出 IllegalStateException 异常。
ps:经常使用这四个方法一起来匹配正则表达式
项目涉及的对象
ObjectMapper
ObjectMapper 是 Jackson 序列化库中的一个核心类,用于将 Java 对象序列化为 JSON 格式的数据或将 JSON 数据反序列化为 Java 对象。
package com.fasterxml.jackson.databind;
public class ObjectMapper extends ObjectCodec implements Versioned, Serializable
objectMapper.readValue()
Jackson 序列化库提供的一个方法,用于将 JSON 字符串反序列化成 Java 对象。
需要注意的是,如果 JSON 字符串与目标 Java 对象的类型不匹配,则会抛出异常。
Map attribute;
try {
attribute = objectMapper.readValue(postsParam.getAttribute(), Map.class);
//调用 readValue() 方法,将 postsParam.getAttribute() 返回的 JSON 字符串反序列化成一个 Map 对象。
} catch (JsonProcessingException e) {
// 处理异常
}
正则表达式
匹配图片链接
\!\[(.*)\]\((.*)\)
![image description](image URL)
image description 表示图片的描述信息,image URL 表示图片的链接地址。
\\! 表示匹配感叹号字符 !,因为感叹号在正则表达式中有特殊含义,需要进行转义。
\\[ 和 \\] 表示匹配方括号字符 [ 和 ],同样需要进行转义。
(.*) 表示匹配任意字符,使用括号将其括起来,以便在后面的匹配中使用。
\\( 和 \\) 表示匹配圆括号字符 ( 和 ),同样需要进行转义。
.* 表示匹配任意数量的字符,包括 0 个字符。
这是一张图片:
![cute cat](https://example.com/cat.jpg)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTest {
public static void main(String[] args) {
String markdown = "这是一张图片:\n![cute cat](https://example.com/cat.jpg)";
String regex = "\\\\!\\\\[(.*)\\\\]\\\\((.*)\\\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(markdown);
if (matcher.find()) {
String description = matcher.group(1);
String url = matcher.group(2);
System.out.println("Description: " + description);
System.out.println("URL: " + url);
}
}
}
Description: cute cat
URL: https://example.com/cat.jpg