如何在属性文件中定义对象数组并从Java程序中读取
我有一个这样的属性文件如何在属性文件中定义对象数组并从Java程序中读取,java,properties,Java,Properties,我有一个这样的属性文件 property[0].name=A property[0].value=1 property[1].name=B property[1].value=2 property[2].name=C property[2].value=3 ArrayList<XYZ> propertiesList = SomeUtility.getProperties("property", XYZ.class); public class SomeUtility { pu
property[0].name=A
property[0].value=1
property[1].name=B
property[1].value=2
property[2].name=C
property[2].value=3
ArrayList<XYZ> propertiesList = SomeUtility.getProperties("property", XYZ.class);
public class SomeUtility {
public static ArrayList getProperties(String key, Class cls) {
//logic
}
}
如何使用ResourceBundle或Properties在普通java程序中将此文件作为类{name,value}的对象列表读取
这是课堂
public class XYZ {
private String name;
private String value;
// Getters & Setters
}
我需要这样
property[0].name=A
property[0].value=1
property[1].name=B
property[1].value=2
property[2].name=C
property[2].value=3
ArrayList<XYZ> propertiesList = SomeUtility.getProperties("property", XYZ.class);
public class SomeUtility {
public static ArrayList getProperties(String key, Class cls) {
//logic
}
}
我可能不太明白您到底想要什么,所以请随时纠正我,并给我更多的约束条件,但这里有一个简单的方法来读取项目中某个位置的
属性
文件:
private static void readPropertiesFile(String path) throws IOException {
java.util.Map<String, String> map = new java.util.LinkedHashMap<>();
Properties properties = new Properties();
InputStream inputStream = new FileInputStream(path);
properties.load(inputStream);
for (String name : properties.stringPropertyNames()) {
map.put(name, properties.getProperty(name));
}
for (java.util.Map.Entry<String, String> entry : map.entrySet()) {
System.out.printf("Property Key: %s, Property Value: %s%n", entry.getKey(), entry.getValue());
}
}
我可能不太明白您到底想要什么,所以请随时纠正我,并给我更多的约束条件,但这里有一个简单的方法来读取项目中某个位置的
属性
文件:
private static void readPropertiesFile(String path) throws IOException {
java.util.Map<String, String> map = new java.util.LinkedHashMap<>();
Properties properties = new Properties();
InputStream inputStream = new FileInputStream(path);
properties.load(inputStream);
for (String name : properties.stringPropertyNames()) {
map.put(name, properties.getProperty(name));
}
for (java.util.Map.Entry<String, String> entry : map.entrySet()) {
System.out.printf("Property Key: %s, Property Value: %s%n", entry.getKey(), entry.getValue());
}
}
这是我写的解决方案,但它涉及到Reflect和Gson。有没有更好的办法?任何像Apache一样经过微调的可用内容
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.lang.reflect.Field;
import java.util.*;
public class ListResourceBundle {
public static final Gson gson = new Gson();
private final ResourceBundle bundle;
public ListResourceBundle(ResourceBundle bundle) {
this.bundle = bundle;
}
public List<?> getProperties(String key, Class<?> cls) {
final int maxArraySize = getMaxArraySize(key, getMatchingKeys(key));
final List<String> fields = getFields(cls);
final List<Object> result = new ArrayList<>();
for (int i = 0; i < maxArraySize; i++) {
JsonObject jsonObject = new JsonObject();
for (String field : fields) {
jsonObject.addProperty(field, getStringOrNull(key + "[" + i + "]." + field));
}
result.add(gson.fromJson(jsonObject, cls));
}
System.out.println("result.toString() = " + result.toString());
return result;
}
public List<String> getMatchingKeys(String key) {
Enumeration<String> keys = bundle.getKeys();
List<String> matchingKeys = new ArrayList<>();
while(keys.hasMoreElements()) {
String k = keys.nextElement();
if(k.startsWith(key)) {
matchingKeys.add(k);
}
}
Collections.sort(matchingKeys);
return matchingKeys;
}
public int getMaxArraySize(String key, List<String> matchingKeys) {
int maxArraySize = 0;
for (int i = 0; ; i++) {
boolean indexAvailable = false;
for (String matchingKey : matchingKeys) {
if(matchingKey.startsWith(key + "[" + i + "]")) {
indexAvailable = true;
break;
}
}
if(indexAvailable) {
maxArraySize++;
} else {
break;
}
}
return maxArraySize;
}
public String getStringOrNull(String key) {
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
return null;
}
}
public List<String> getFields(Class<?> cls) {
final List<String> fields = new ArrayList<>();
for (Field field : cls.getDeclaredFields()) {
fields.add(field.getName());
}
return fields;
}
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("com.example.application.resources.Resource");
ListResourceBundle applicationResourceBundle = new ListResourceBundle(bundle);
applicationResourceBundle.getProperties("property", ReportParam.class);
}
}
输出:
result.toString() = [
ReportParam{name='A', value='1'},
ReportParam{name='B', value='2'},
ReportParam{name='C', value='3'}]
Process finished with exit code 0
这是我写的解决方案,但它涉及到Reflect和Gson。有没有更好的办法?任何像Apache一样经过微调的可用内容
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.lang.reflect.Field;
import java.util.*;
public class ListResourceBundle {
public static final Gson gson = new Gson();
private final ResourceBundle bundle;
public ListResourceBundle(ResourceBundle bundle) {
this.bundle = bundle;
}
public List<?> getProperties(String key, Class<?> cls) {
final int maxArraySize = getMaxArraySize(key, getMatchingKeys(key));
final List<String> fields = getFields(cls);
final List<Object> result = new ArrayList<>();
for (int i = 0; i < maxArraySize; i++) {
JsonObject jsonObject = new JsonObject();
for (String field : fields) {
jsonObject.addProperty(field, getStringOrNull(key + "[" + i + "]." + field));
}
result.add(gson.fromJson(jsonObject, cls));
}
System.out.println("result.toString() = " + result.toString());
return result;
}
public List<String> getMatchingKeys(String key) {
Enumeration<String> keys = bundle.getKeys();
List<String> matchingKeys = new ArrayList<>();
while(keys.hasMoreElements()) {
String k = keys.nextElement();
if(k.startsWith(key)) {
matchingKeys.add(k);
}
}
Collections.sort(matchingKeys);
return matchingKeys;
}
public int getMaxArraySize(String key, List<String> matchingKeys) {
int maxArraySize = 0;
for (int i = 0; ; i++) {
boolean indexAvailable = false;
for (String matchingKey : matchingKeys) {
if(matchingKey.startsWith(key + "[" + i + "]")) {
indexAvailable = true;
break;
}
}
if(indexAvailable) {
maxArraySize++;
} else {
break;
}
}
return maxArraySize;
}
public String getStringOrNull(String key) {
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
return null;
}
}
public List<String> getFields(Class<?> cls) {
final List<String> fields = new ArrayList<>();
for (Field field : cls.getDeclaredFields()) {
fields.add(field.getName());
}
return fields;
}
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("com.example.application.resources.Resource");
ListResourceBundle applicationResourceBundle = new ListResourceBundle(bundle);
applicationResourceBundle.getProperties("property", ReportParam.class);
}
}
输出:
result.toString() = [
ReportParam{name='A', value='1'},
ReportParam{name='B', value='2'},
ReportParam{name='C', value='3'}]
Process finished with exit code 0
我知道回答有点晚,但如果我正确理解您的问题陈述,您可以使用:
@ConfigurationProperties
完成你的工作。
为了方便起见,这里是我的带有YAML文件的spring引导示例(同样可以通过属性文件实现)
应用程序。yaml:
xyz:
xyzprops :
-
name: cbc
value: 441
-
name: obc
value: 443
@Component
@ConfigurationProperties(prefix = "xyz")
public class XYZ{
private List<XYZProps> xyzprops;
public List<XYZProps> getXyzprops() {
return xyzprops;
}
public void setXyzprops(List<XYZProps> xyzprops) {
this.xyzprops = xyzprops;
}
public class XYZProps{
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
XYZ类:
xyz:
xyzprops :
-
name: cbc
value: 441
-
name: obc
value: 443
@Component
@ConfigurationProperties(prefix = "xyz")
public class XYZ{
private List<XYZProps> xyzprops;
public List<XYZProps> getXyzprops() {
return xyzprops;
}
public void setXyzprops(List<XYZProps> xyzprops) {
this.xyzprops = xyzprops;
}
public class XYZProps{
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
@组件
@配置属性(前缀=“xyz”)
公共类XYZ{
私有列表xyzprops;
公共列表getXyzprops(){
返回xyzprops;
}
公共无效设置xyzprops(列出xyzprops){
this.xyzprops=xyzprops;
}
公共类XYZProps{
字符串名;
字符串值;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getValue(){
返回值;
}
公共void设置值(字符串值){
这个值=值;
}
}
}
然后在您想使用它的地方@Autowire XYZ。我知道回答有点晚,但如果我正确理解您的问题陈述,您可以使用:
@ConfigurationProperties
完成你的工作。
为了方便起见,这里是我的带有YAML文件的spring引导示例(同样可以通过属性文件实现)
应用程序。yaml:
xyz:
xyzprops :
-
name: cbc
value: 441
-
name: obc
value: 443
@Component
@ConfigurationProperties(prefix = "xyz")
public class XYZ{
private List<XYZProps> xyzprops;
public List<XYZProps> getXyzprops() {
return xyzprops;
}
public void setXyzprops(List<XYZProps> xyzprops) {
this.xyzprops = xyzprops;
}
public class XYZProps{
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
XYZ类:
xyz:
xyzprops :
-
name: cbc
value: 441
-
name: obc
value: 443
@Component
@ConfigurationProperties(prefix = "xyz")
public class XYZ{
private List<XYZProps> xyzprops;
public List<XYZProps> getXyzprops() {
return xyzprops;
}
public void setXyzprops(List<XYZProps> xyzprops) {
this.xyzprops = xyzprops;
}
public class XYZProps{
String name;
String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
@组件
@配置属性(前缀=“xyz”)
公共类XYZ{
私有列表xyzprops;
公共列表getXyzprops(){
返回xyzprops;
}
公共无效设置xyzprops(列出xyzprops){
this.xyzprops=xyzprops;
}
公共类XYZProps{
字符串名;
字符串值;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getValue(){
返回值;
}
公共void设置值(字符串值){
这个值=值;
}
}
}
然后在需要使用它的地方使用@Autowire XYZ。我会使用JSON:
在您的文件中:property=[{“name”:“A”,“value”:“1”},{“name”:“B”,“value”:“2”},{“name”:“C”,“value”:“3”}]
然后使用com.google.gson.gson
(或任何其他)库对其进行反序列化:ArrayList属性列表代码>
propertiesList=new gsonbuilder().create().fromjson(property,propertiesList.class)代码>
注意:我还没有测试过这段代码,而且我对java不是很熟悉,所以我相信有更好、更干净的方法来实现这一点。我会使用JSON:
在您的文件中:
property=[{“name”:“A”,“value”:“1”},{“name”:“B”,“value”:“2”},{“name”:“C”,“value”:“3”}]
然后使用com.google.gson.gson
(或任何其他)库对其进行反序列化:
ArrayList属性列表代码>
propertiesList=new gsonbuilder().create().fromjson(property,propertiesList.class)代码>
注意:我还没有测试过这段代码,而且我对java不是很熟悉,所以我确信有更好、更干净的方法来实现这一点。你不能将其作为简单文件阅读吗?我可以作为文本文件阅读,但不想进行手动解析。正在寻找任何已经存在的预定义util或方法?您不想手动解析它有什么特别的原因吗?如果我手动解析它,我必须定义列表大小(这里是3)。但如果它在内置解析,我可以向属性添加更多值,并反映结果。我知道有办法做到这一点,但我希望有一个更干净的实施。比如来自Spring的@PropertySource。我提供了一种非常简单的读取属性文件的方法,如果这能回答您的问题,请告诉我。您不能将其作为简单文件读取吗?我可以作为文本文件读取,但不想进行手动解析。正在寻找任何已经存在的预定义util或方法?您不想手动解析它有什么特别的原因吗?如果我手动解析它,我必须定义列表大小(这里是3)。但如果它在内置解析,我可以向属性添加更多值,并反映结果。我知道有办法做到这一点,但我希望有一个更干净的实施。比如来自Spring的@PropertySource。我提供了一种非常简单的读取属性文件的方法,如果这能回答您的问题,请告诉我。谢谢Matthew。。。但这不是我想要的。需要将此属性文件转换为ArrayList,其中XYZ是{name,value}的类。是否在某个地方定义了此类?我看到的只是你样本中的数字和字母。如果你提供了整个属性文件,这样我就有了一些有形的东西可以处理,这也会很有帮助。编辑了问题摘要。请查收,你能解释一下吗