fix resource

This commit is contained in:
Looly
2025-04-26 13:08:44 +08:00
parent 05dfc221a5
commit f8bf24aa0c
10 changed files with 88 additions and 39 deletions

View File

@@ -55,6 +55,11 @@ public class PropDesc {
*/
protected Invoker setter;
private Boolean hasTransientForGetter;
private Boolean hasTransientForSetter;
private Boolean isReadable;
private Boolean isWritable;
/**
* 构造<br>
* Getter和Setter方法设置为默认可访问
@@ -181,27 +186,12 @@ public class PropDesc {
* @since 5.4.2
*/
public boolean isReadable(final boolean checkTransient) {
Field field = null;
if (this.fieldInvoker instanceof FieldInvoker) {
field = ((FieldInvoker) this.fieldInvoker).getField();
}
Method getterMethod = null;
if (this.getter instanceof MethodInvoker) {
getterMethod = ((MethodInvoker) this.getter).getMethod();
}
cacheReadable();
// 检查transient关键字和@Transient注解
if (checkTransient && isTransientForGet(field, getterMethod)) {
if(checkTransient && this.hasTransientForGetter){
return false;
}
// 检查@PropIgnore注解
if (isIgnoreGet(field, getterMethod)) {
return false;
}
// 检查是否有getter方法或是否为public修饰
return null != getterMethod || ModifierUtil.isPublic(field);
return this.isReadable;
}
/**
@@ -260,27 +250,12 @@ public class PropDesc {
* @since 5.4.2
*/
public boolean isWritable(final boolean checkTransient) {
Field field = null;
if (this.fieldInvoker instanceof FieldInvoker) {
field = ((FieldInvoker) this.fieldInvoker).getField();
}
Method setterMethod = null;
if (this.setter instanceof MethodInvoker) {
setterMethod = ((MethodInvoker) this.setter).getMethod();
}
cacheWritable();
// 检查transient关键字和@Transient注解
if (checkTransient && isTransientForSet(field, setterMethod)) {
if(checkTransient && this.hasTransientForSetter){
return false;
}
// 检查@PropIgnore注解
if(isIgnoreSet(field, setterMethod)){
return false;
}
// 检查是否有setter方法或是否为public修饰
return null != setterMethod || ModifierUtil.isPublic(field);
return this.isWritable;
}
/**
@@ -373,6 +348,66 @@ public class PropDesc {
// region ----- private methods
/**
* 缓存读取属性的可读性如果已经检查过直接返回true
*/
private void cacheReadable(){
if(null != this.isReadable){
return;
}
Field field = null;
if (this.fieldInvoker instanceof FieldInvoker) {
field = ((FieldInvoker) this.fieldInvoker).getField();
}
Method getterMethod = null;
if (this.getter instanceof MethodInvoker) {
getterMethod = ((MethodInvoker) this.getter).getMethod();
}
// 检查transient关键字和@Transient注解
this.hasTransientForGetter = isTransientForGet(field, getterMethod);
// 检查@PropIgnore注解
if (isIgnoreGet(field, getterMethod)) {
this.isReadable = false;
return;
}
// 检查是否有getter方法或是否为public修饰
this.isReadable = null != getterMethod || ModifierUtil.isPublic(field);
}
/**
* 缓存写入属性的可写性如果已经检查过直接返回true
*/
private void cacheWritable(){
if(null != this.isWritable){
return;
}
Field field = null;
if (this.fieldInvoker instanceof FieldInvoker) {
field = ((FieldInvoker) this.fieldInvoker).getField();
}
Method setterMethod = null;
if (this.setter instanceof MethodInvoker) {
setterMethod = ((MethodInvoker) this.setter).getMethod();
}
// 检查transient关键字和@Transient注解
this.hasTransientForSetter = isTransientForSet(field, setterMethod);
// 检查@PropIgnore注解
if(isIgnoreSet(field, setterMethod)){
this.isWritable = false;
return;
}
// 检查是否有setter方法或是否为public修饰
this.isWritable = null != setterMethod || ModifierUtil.isPublic(field);
}
/**
* 通过Getter和Setter方法中找到属性类型
*

View File

@@ -22,6 +22,7 @@ import cn.hutool.v7.core.reflect.method.MethodNameUtil;
import cn.hutool.v7.core.reflect.method.MethodUtil;
import cn.hutool.v7.core.util.BooleanUtil;
import java.io.Serial;
import java.lang.reflect.Method;
import java.util.Map;
@@ -37,6 +38,7 @@ import java.util.Map;
* @since 6.0.0
*/
public class SimpleBeanDesc extends AbstractBeanDesc {
@Serial
private static final long serialVersionUID = 1L;
/**

View File

@@ -25,6 +25,7 @@ import cn.hutool.v7.core.reflect.method.MethodUtil;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.core.util.BooleanUtil;
import java.io.Serial;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
@@ -44,6 +45,7 @@ import java.util.Map;
* @since 3.1.2
*/
public class StrictBeanDesc extends AbstractBeanDesc {
@Serial
private static final long serialVersionUID = 1L;
/**

View File

@@ -21,6 +21,7 @@ import cn.hutool.v7.core.bean.PropDesc;
import cn.hutool.v7.core.lang.Assert;
import cn.hutool.v7.core.map.CaseInsensitiveMap;
import java.io.Serial;
import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -32,6 +33,7 @@ import java.util.Map;
* @since 6.0.0
*/
public abstract class AbstractBeanDesc implements BeanDesc {
@Serial
private static final long serialVersionUID = 1L;
/**

View File

@@ -314,7 +314,7 @@ public class FileUtil {
}
// 如果用户需要相对项目路径则使用project:前缀
if (path.startsWith("project:")) {
if (path.startsWith(UrlUtil.PROJECT_URL_PREFIX)) {
return new File(path);
}

View File

@@ -24,6 +24,7 @@ import cn.hutool.v7.core.net.url.UrlUtil;
import cn.hutool.v7.core.text.StrUtil;
import cn.hutool.v7.core.util.ObjUtil;
import java.io.Serial;
import java.net.URL;
/**
@@ -35,6 +36,7 @@ import java.net.URL;
*
*/
public class ClassPathResource extends UrlResource {
@Serial
private static final long serialVersionUID = 1L;
private final String path;

View File

@@ -23,6 +23,7 @@ import cn.hutool.v7.core.util.ObjUtil;
import java.io.File;
import java.io.InputStream;
import java.io.Serial;
import java.io.Serializable;
import java.net.URL;
import java.nio.file.Path;
@@ -33,6 +34,7 @@ import java.nio.file.Path;
* @author Looly
*/
public class FileResource implements Resource, Serializable {
@Serial
private static final long serialVersionUID = 1L;
private final File file;

View File

@@ -243,7 +243,7 @@ public class ResourceUtil {
*/
public static Resource getResource(final String path) {
if (StrUtil.isNotBlank(path)) {
if (path.startsWith(UrlUtil.FILE_URL_PREFIX) || FileUtil.isAbsolutePath(path)) {
if (StrUtil.startWithAny(path, UrlUtil.FILE_URL_PREFIX, UrlUtil.PROJECT_URL_PREFIX) || FileUtil.isAbsolutePath(path)) {
return new FileResource(path);
}
}

View File

@@ -55,6 +55,10 @@ public class UrlUtil {
* 针对ClassPath路径的伪协议前缀兼容Spring: "classpath:"
*/
public static final String CLASSPATH_URL_PREFIX = "classpath:";
/**
* 针对project路径的伪协议前缀: "project:"
*/
public static final String PROJECT_URL_PREFIX = "project:";
/**
* URL 前缀表示文件: "file:"
*/

View File

@@ -59,6 +59,6 @@ public class ResourceUtilTest {
@Test
void getResourceTest2() {
// project:开头表示基于项目的相对路径,此处无文件报错
Assertions.assertThrows(NoResourceException.class, () -> ResourceUtil.getResource("project:test.xml"));
Assertions.assertThrows(NoResourceException.class, () -> ResourceUtil.getResource("project:test.xml").getStream());
}
}