mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix resource
This commit is contained in:
@@ -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方法中找到属性类型
|
||||||
*
|
*
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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:"
|
||||||
*/
|
*/
|
||||||
|
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user