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; protected Invoker setter;
private Boolean hasTransientForGetter;
private Boolean hasTransientForSetter;
private Boolean isReadable;
private Boolean isWritable;
/** /**
* 构造<br> * 构造<br>
* Getter和Setter方法设置为默认可访问 * Getter和Setter方法设置为默认可访问
@@ -181,27 +186,12 @@ public class PropDesc {
* @since 5.4.2 * @since 5.4.2
*/ */
public boolean isReadable(final boolean checkTransient) { public boolean isReadable(final boolean checkTransient) {
Field field = null; cacheReadable();
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注解 if(checkTransient && this.hasTransientForGetter){
if (checkTransient && isTransientForGet(field, getterMethod)) {
return false; return false;
} }
return this.isReadable;
// 检查@PropIgnore注解
if (isIgnoreGet(field, getterMethod)) {
return false;
}
// 检查是否有getter方法或是否为public修饰
return null != getterMethod || ModifierUtil.isPublic(field);
} }
/** /**
@@ -260,27 +250,12 @@ public class PropDesc {
* @since 5.4.2 * @since 5.4.2
*/ */
public boolean isWritable(final boolean checkTransient) { public boolean isWritable(final boolean checkTransient) {
Field field = null; cacheWritable();
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注解 if(checkTransient && this.hasTransientForSetter){
if (checkTransient && isTransientForSet(field, setterMethod)) {
return false; return false;
} }
return this.isWritable;
// 检查@PropIgnore注解
if(isIgnoreSet(field, setterMethod)){
return false;
}
// 检查是否有setter方法或是否为public修饰
return null != setterMethod || ModifierUtil.isPublic(field);
} }
/** /**
@@ -373,6 +348,66 @@ public class PropDesc {
// region ----- private methods // 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方法中找到属性类型 * 通过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.reflect.method.MethodUtil;
import cn.hutool.v7.core.util.BooleanUtil; import cn.hutool.v7.core.util.BooleanUtil;
import java.io.Serial;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
@@ -37,6 +38,7 @@ import java.util.Map;
* @since 6.0.0 * @since 6.0.0
*/ */
public class SimpleBeanDesc extends AbstractBeanDesc { public class SimpleBeanDesc extends AbstractBeanDesc {
@Serial
private static final long serialVersionUID = 1L; 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.text.StrUtil;
import cn.hutool.v7.core.util.BooleanUtil; import cn.hutool.v7.core.util.BooleanUtil;
import java.io.Serial;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
@@ -44,6 +45,7 @@ import java.util.Map;
* @since 3.1.2 * @since 3.1.2
*/ */
public class StrictBeanDesc extends AbstractBeanDesc { public class StrictBeanDesc extends AbstractBeanDesc {
@Serial
private static final long serialVersionUID = 1L; 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.lang.Assert;
import cn.hutool.v7.core.map.CaseInsensitiveMap; import cn.hutool.v7.core.map.CaseInsensitiveMap;
import java.io.Serial;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@@ -32,6 +33,7 @@ import java.util.Map;
* @since 6.0.0 * @since 6.0.0
*/ */
public abstract class AbstractBeanDesc implements BeanDesc { public abstract class AbstractBeanDesc implements BeanDesc {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**

View File

@@ -314,7 +314,7 @@ public class FileUtil {
} }
// 如果用户需要相对项目路径则使用project:前缀 // 如果用户需要相对项目路径则使用project:前缀
if (path.startsWith("project:")) { if (path.startsWith(UrlUtil.PROJECT_URL_PREFIX)) {
return new File(path); 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.text.StrUtil;
import cn.hutool.v7.core.util.ObjUtil; import cn.hutool.v7.core.util.ObjUtil;
import java.io.Serial;
import java.net.URL; import java.net.URL;
/** /**
@@ -35,6 +36,7 @@ import java.net.URL;
* *
*/ */
public class ClassPathResource extends UrlResource { public class ClassPathResource extends UrlResource {
@Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String path; private final String path;

View File

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

View File

@@ -243,7 +243,7 @@ public class ResourceUtil {
*/ */
public static Resource getResource(final String path) { public static Resource getResource(final String path) {
if (StrUtil.isNotBlank(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); return new FileResource(path);
} }
} }

View File

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

View File

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