I have been trying to load string values by inserting the keys from properties file inside the enum constructor. But instead of setting the values, it's setting the keys only.
My errorcodes.properties have this content
error.id.required.message=Id is required to get the details. error.id.required.code=110
and enum file is like this:
`public enum ErrorCodes {
ID_REQUIRED("error.id.required.message",
"error.id.required.code"),
ID_INVALID("error.id.invalid.message",
"error.id.invalid.code");
private final String msg;
private final String code;
private ErrorCodes(String msg, String code) {
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public String getCode() {
return code;
}
}`
So I created an exception which would take one of the above defined enum as an argument and throw a custom exception with message as "Id is required to get the details." and the code as "110".
e.g., throw new CustomException(ErrorCodes.ID_REQUIRED)
Instead the response came as
"errorCode": "error.id.required.code"
"errorMessage": "error.id.required.message"
Please help! Thanks.
CodePudding user response:
To fix this, you must load the properties file and retrieve the values using the keys passed to the enum constructor.
You can use the java.util.Properties class to load the properties file and retrieve the values. Here is an example of how you can modify your code to load the values from the properties file:
public enum ErrorCodes {
ID_REQUIRED("error.id.required"),
ID_INVALID("error.id.invalid");
private final String msg;
private final String code;
static {
properties = new Properties();
RuntimeException initError;
try {
InputStream input = getClass().getResourceAsStream("errorcodes.properties")
properties.load(input);
} catch (IOException e) {
initError = RuntimeException initError = new RuntimeException("Unhandled Error: ", e)
}
}
private ErrorCodes(String key) {
this.msg = key ".message";
this.code = key ".code";
}
public String getMsg() {
return getProperty(msg);
}
public String getCode() {
return getProperty(code);
}
private static String getProperty(String key) {
if (initError != null) {
throw initError;
}
return properties.getProperty(key);
}
}
This way, the enum constructor takes the property's key and uses it to look up the values from the properties file.
As a side note, you should also ensure that the errorcodes.properties
is in the classpath of your application.
CodePudding user response:
In general there's no good idea to use Enum
like this. Remember, that enum's constant is singleton, therefore you can't use this like this.
I think it's better to have separate class, where you can encapsulate this logic:
- Read property file
- Get an
Enum
and retrieve only related data from the file - Declare two
Map
to savemessage
andcode
byErrorCode
- Getters to retreive
message
andcode
byErrorCode
ErrorCode
andErrorCodeStore
should be in the same package
This is an enum ErrorCode
:
@lombok.RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public enum ErrorCode {
ID_REQUIRED("error.id.required.message", "error.id.required.code"),
ID_INVALID("error.id.invalid.message", "error.id.invalid.code");
final String message;
final String code;
public final String getMessage() {
return ErrorCodeStore.getInstance().getValue(message);
}
public final String getCode() {
return ErrorCodeStore.getInstance().getValue(code);
}
}
This is ErrorCodeStore
:
@lombok.RequiredArgsConstructor(access = AccessLevel.PRIVATE)
final class ErrorCodeStore {
private static ErrorCodeStore instance;
public static ErrorCodeStore getInstance() {
if (instance == null)
throw new RuntimeException("ErrorCodeStore instance should be"
" initialized");
return instance;
}
private final Properties properties;
// InputStream should be explicitly closed
public static ErrorCodeStore initFrom(InputStream in) throws IOException {
Properties properties = new Properties();
properties.load(in);
return instance = new ErrorCodeStore(properties);
}
String getValue(String key) {
return properties.getProperty(key, key);
}
}
Demo
public static void main(String[] args) throws IOException {
ErrorCodeStore.initFrom(Main.class.getResourceAsStream("/errorcodes.properties"));
System.out.println(ErrorCode.ID_REQUIRED.getMessage()); // Id is required to get the details.
System.out.println(ErrorCode.ID_REQUIRED.getCode()); // 110
System.out.println(ErrorCode.ID_INVALID.getMessage()); // error.id.invalid.message
System.out.println(ErrorCode.ID_INVALID.getCode()); // error.id.invalid.code
}