在我的网络应用程序中,在对对象进行一些更改期间,我需要发送有关对象中发生的更改的邮件。 我的问题是如何为此编写一个监听器。 请给我一些关于此的文章。 感谢
答案 0 :(得分:22)
典型的实现可能是这样的:您的对象是可观察的。因此,每次(观察到的)值之一发生更改时,都会触发事件并通知所有已注册的侦听器。其中一个侦听器现在将被设计为接收通知并创建和发送EMail(Java Mail API)
让我们看一个我们可以观察的样本bean:
public class Bean implements Observable{
// code to maintain listeners
private List<Listener> listeners = new ArrayList<Listener>();
public void add(Listener listener) {listeners.add(listener);}
public void remove(Listener listener) {listeners.remove(listener);}
// a sample field
private int field;
public int getField() {return field;}
public int setField(int value) {
field = value;
fire("field");
}
// notification code
private void fire(String attribute) {
for (Listener listener:listeners) {
fieldChanged(this, attribute);
}
}
}
监听器界面:
public interface Listener {
public void fieldChanged(Object source, String attrbute);
}
Observable界面:
public interface Observable {
public void add(Listener listener);
public void remove(Listener listener);
}
和EMailer:
public class Sender implements Listener {
public void register(Observable observable) {observable.add(this);}
public void unregister(Observable observable) {observable.remove(this);}
public void fieldChanged(Object source, String attribute) {
sendEmail(source, attribute); // this has to be implemented
}
}
修改强> 纠正了setter方法中的一个丑陋错误 - 现在在属性设置之后触发了事件。反过来说,副作用是,如果听众读了改变的属性,他仍然会看到旧的,不变的值...
答案 1 :(得分:6)
如果您只是想了解被修改对象的属性,我建议您使用PropertyChangeListener
。这样,您可以使用PropertyChangeSupport
实用程序类来管理侦听器实例和事件触发。你也避免重新发明轮子。
对于更多定制事件触发,我建议您定义自己的侦听器界面。
示例类
public class MyBean {
private final PropertyChangeSupport support;
private int i;
private boolean b;
public MyBean() {
this.support = new PropertyChangeSupport(this);
}
// Accessors and Mutators. Mutating a property causes a PropertyChangeEvent
// to be fired.
public int getI() { return i; }
public void setI(int i) {
int oldI = this.i;
this.i = i;
support.firePropertyChange("i", oldI, this.i);
}
public boolean getB() { return b; }
public void setB(boolean b) {
boolean oldB = this.b;
this.b = b;
support.firePropertyChange("b", oldB, this.b);
}
// Wrapper methods that simply delegate listener management to
// the underlying PropertyChangeSupport class.
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
// You would typically call this method rather than addPropertyChangeListener(PropertyChangeListener)
// in order to register your listener with a specific property.
// This then avoids the need for large if-then statements within your listener
// implementation in order to check which property has changed.
if (!"i".equals(propertyName) && !"b".equals(propertyName)) {
throw new IllegalArgumentException("Invalid property name: " + propertyName);
}
support.addPropertyChangeListener(propertyName, l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
support.removePropertyChangeListener(l);
}
public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
support.removePropertyChangeListener(propertyName, l);
}
}
使用示例
// Create a new instance of our observable MyBean class.
MyBean bean = new MyBean();
// Create a PropertyChangeListener specifically for listening to property "b".
PropertyChangeListener listener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
assert "b".equals(evt.getPropertyName());
boolean oldB = (Boolean) evt.getOldValue();
boolean newB = (Boolean) evt.getNewValue();
System.err.println(String.format("Property b updated: %b -> %b, oldB, newB));
}
}
// Register listener with specific property name. It will only be called back
// if this property changes, *not* the "i" int property.
bean.addPropertyChangeListener("b", listener);
答案 2 :(得分:3)
您应该使用 Observer Design Pattern 。此模式使用以下类:
这是一个例子。
观察员:
public class EmailObserver implements Observer
{
@Override
public void update(Observable obj, Object arg)
{
if (obj instanceof YourObject)
{
// TODO Send the mail or whatever, you have access to the modified object through obj
// In arg you can put some additional parameter, like the modified field
}
}
}
可观察对象:
public static class YourObject extends Observable
{
public void setSomething(Object parameter)
{
// TODO some modification in YourObject
setChanged(); // From Observable : the object has changed
notifyObservers(parameter); // Notify the observer about the change
}
}
主要课程:
public static void main(String[] args)
{
// Create YourObject
YourObject o = new YourObject();
// create an observer
EmailObserver emailObserver = new EmailObserver();
// subscribe the observer to your object
o.addObserver(emailObserver);
// Now you can modify your object, changes will be notified by email
o.setSomething(...);
}
答案 3 :(得分:1)