我为我们的一个应用程序编写了一个JMX接口。然后,另一个应用程序连接并允许用户通过此管理工具远程查看各种状态相关属性/调用操作。我偶然发现了一个小错误,我们的数据库连接设置通过JMX公开,密码未加密。我想标记应该使用某些标志进行模糊处理的属性/操作,但它看起来并不像MBeanAttributeInfo或MBeanOperationInfo对象支持为名称和描述添加任何用户定义的值异常。我想我可以像
那样划分描述字段String desc = getAttrDesc() + ";" + getIsObfuscated();
但我不太喜欢这种方法。那么问题是,有没有更好的方法来为属性/操作信息对象或Dynamic MBean本身提供任意键值对?它不必在info对象本身上,只要我可以在管理工具方面匹配它们。任何见解将不胜感激。
为了澄清,当我构造MBeanOperationInfo(为了示例而忽略了属性)时,我这样做:
LinkedList<MBeanOperationInfo> opperInfos = new LinkedList<MBeanOperationInfo>();
for (Method m : m_InstObj.getMethods()) {
InstrumentedOperation anno = m.getAnnotation(InstrumentedOperation.class);
String desc = anno.description();
opperInfos.add(new MBeanOperationInfo(desc, m));
}
m_Operations = new MBeanOperationInfo[opperInfos.size()];
int I = 0;
for (MBeanOperationInfo info : opperInfos) {
m_Operations[I] = info;
I++;
}
我希望InstrumentedOperation注释有一个混淆的字段,我可以像这样使用:
anno.obfuscated(); // <- retreives a boolean set as a compile time constant on the annotation
并且能够在Info对象中包含此值。
然后在接收方我这样做:
MBeanOperationInfo[] operInfos = conn.getMBeanInfo(name).getOperations();
for (MBeanOperationInfo info : operInfos) {
String propName = getPropNameFromInfo(info.getName());
if (!uniqueSettings.contains(propName)) {
// this setting hasn't been handled, get the getters and setters and make the method map
String getter = getGetterForSetting(operInfos, info.getName());
String setter = getSetterForSetting(operInfos, info.getName());
Object value = conn.invoke(name, getter, new Object[] {}, new String[] {});
if (getter != null && setter != null) {
SettingMethodMap map = new SettingMethodMap(name.getKeyProperty("type"), propName, info.getName(), setter, getter, value);
uniqueSettings.add(propName);
m_Settings.add(map);
}
}
}
在这里,我希望能够通过某种机制来检索键值对,所以我知道我需要处理不同的字段并在编辑器中对其进行模糊处理。
答案 0 :(得分:2)
这可以使用javax.management.DescriptorKey。
来实现例如,使用我为此修改的代码示例,使用standard mbean:
“混淆”注释:
import java.lang.annotation.*;
import javax.management.DescriptorKey;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Obfuscated {
@DescriptorKey("obfuscated")
boolean value() default true;
}
MBean接口:
public interface LoginMBean {
String getName();
@Obfuscated
String getPassword();
}
MBean实施:
public class Login implements LoginMBean {
private final String user;
private final String password;
public Login(String user, String password) {
this.user = user;
this.password = password;
}
@Override public String getName() { return user; }
@Override public String getPassword() { return password; }
}
注册MBean并浏览其信息的一些代码:
import java.lang.management.ManagementFactory;
import javax.management.*;
public class Main {
public static void main(String[] args) {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName mbeanName = new ObjectName("com.mydomain", "type", "login");
server.registerMBean(
new StandardMBean(new Login("John Doe", "password"), LoginMBean.class), mbeanName);
MBeanInfo mbeanInfo = server.getMBeanInfo(mbeanName);
MBeanAttributeInfo[] attrs = mbeanInfo.getAttributes();
for (MBeanAttributeInfo attr: attrs) {
Descriptor desc = attr.getDescriptor();
boolean obfuscated = false;
if (desc.getFieldValue("obfuscated") != null) {
obfuscated = (Boolean) desc.getFieldValue("obfuscated");
}
if (obfuscated) System.out.printf("field '%s' is obfuscated%n", attr.getName());
else {
Object value = server.getAttribute(mbeanName, attr.getName());
System.out.printf("value of field '%s' is '%s'%n",
attr.getName(), value == null ? "null" : value.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后,运行Main后的输出:
value of field 'Name' is 'John Doe' field 'Password' is obfuscated