我是一个刚开始学习RMI和JFrame的人,目前遇到了一个异常问题。我正在编写一个客户端/服务器交互程序,用于从雅虎数据库中获取股票信息。
以下是我的代码:
package stockquote;
public class StockQuote{
public double currentPrice, priceChange, dailyLow, dailyHigh;
public StockQuote(double price, double change, double low, double high){
currentPrice = price;
priceChange = change;
dailyLow = low;
dailyHigh = high;
}
public StockQuote(){
currentPrice = 0;
priceChange = 0;
dailyLow = 0;
dailyHigh = 0;
}
}
package stockquote;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface StockQuoteInterface extends Remote{
public StockQuote getQuote(String symbol) throws RemoteException;
}
package stockquote;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
import java.io.*;
import java.util.Properties;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.rmi.RemoteException;
import java.util.*;
public class StockQuoteServer implements StockQuoteInterface{
public StockQuote getQuote(String symbol) throws RemoteException{
StockQuote information = new StockQuote();
try{
URL url = new URL("http://download.finance.yahoo.com/d/quotes.csv?s=" + symbol + "&f=l1c1hg");
URLConnection conn = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String quoteString = in.readLine();
in.close();
String[] data = quoteString.split(",");
information.currentPrice = Double.parseDouble(data[0]);
information.priceChange = Double.parseDouble(data[1]);
information.dailyHigh = Double.parseDouble(data[2]);
information.dailyLow = Double.parseDouble(data[3]);
}catch(Exception e){
e.printStackTrace();
}
return information;
}
public static void main(String[] args) throws Exception {
try {
StockQuoteServer obj = new StockQuoteServer();
StockQuoteInterface stub = (StockQuoteInterface) UnicastRemoteObject.exportObject(obj, 0);
Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
registry.rebind("StockQuoteServer", stub);
System.err.println("StockQuote Server is running.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package stockquote;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
public class StockQuoteClient extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
private static StockQuoteInterface stockQuote;
private JTextField symbolField = new JTextField(10);
private JTextField currentPriceField = new JTextField(10);
private JTextField priceChangeField = new JTextField(10);
private JTextField dailyHighField = new JTextField(10);
private JTextField dailyLowField = new JTextField(10);
private JButton lookup = new JButton("Lookup");
public StockQuoteClient() throws RemoteException{
try {
Registry registry = LocateRegistry.getRegistry("localhost");
stockQuote = (StockQuoteInterface) registry.lookup("StockQuoteServer");
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
this.setLayout(new GridLayout(0,1));
JPanel symbolPanel = new JPanel();
symbolPanel.add(new JLabel("Stock Symbol: "));
symbolPanel.add(symbolField);
this.add(symbolPanel);
this.setLayout(new GridLayout(0,1));
JPanel fieldsPanel = new JPanel();
fieldsPanel.add(new JLabel("Current Price: "));
fieldsPanel.add(currentPriceField);
fieldsPanel.add(new JLabel("Price Change: "));
fieldsPanel.add(priceChangeField);
fieldsPanel.add(new JLabel("Daily High: "));
fieldsPanel.add(dailyHighField);
fieldsPanel.add(new JLabel("Daily Low: "));
fieldsPanel.add(dailyLowField);
this.add(fieldsPanel);
JPanel lookupButtonPanel = new JPanel();
lookupButtonPanel.add(lookup);
this.add(lookupButtonPanel);
lookup.addActionListener(this);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(240, 350);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e){
StockQuote quoteInfo = new StockQuote();
Object source = e.getSource();
try{
if(source == lookup){
String symbol = symbolField.getText().trim();
quoteInfo = stockQuote.getQuote(symbol);
if(quoteInfo.currentPrice == 0.0){
currentPriceField.setText("Error");
priceChangeField.setText("Error");
dailyHighField.setText("Error");
dailyLowField.setText("Error");
}else{
currentPriceField.setText(Double.toString(quoteInfo.currentPrice));
priceChangeField.setText(Double.toString(quoteInfo.priceChange));
dailyHighField.setText(Double.toString(quoteInfo.dailyHigh));
dailyLowField.setText(Double.toString(quoteInfo.dailyLow));
}
}
}catch(RemoteException ex){
ex.printStackTrace();
}
}
public static void main(String[] args) throws RemoteException{
/*StockQuote ggg = new StockQuote();
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a symbol: ");
String symbol = keyboard.nextLine();
ggg = stockQuote.getQuote(symbol);
System.out.println(ggg.currentPrice);*/
new StockQuoteClient();
}
}
这里是我收到的异常信息。
Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: stockquote.StockQuote
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at com.sun.proxy.$Proxy0.getQuote(Unknown Source)
at stockquote.StockQuoteClient.main(StockQuoteClient.java:101)
Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: stockquote.StockQuote
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source)
... 5 more
Caused by: java.io.NotSerializableException: stockquote.StockQuote
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at sun.rmi.server.UnicastRef.marshalValue(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$256(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)