The web services stack is also helpful for accessing an existing web service. For example, you might be interested in accessing a well-known web service from Amazon, eBay, Google, or another popular company. Alternatively, you might choose to access a lesser- known web service, such as one of the services listed on the XMethods directory site (http://www.xmethods.net/ve2/index.po).
Consider a SkyViewapplication that obtains images from the image archive main- tained by Sloan Digital Sky Survey (SDSS) (http://www.sdss.org/). Images are obtained via the Image Cutout web service, which is described by the WSDL file at http://casjobs.
sdss.org/ImgCutoutDR5/ImgCutout.asmx?wsdl. Listing 10-8 presents SkyView’s source code.
Listing 10-8.SkyView.java
// SkyView.java import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
C H A P T E R 1 0 ■ S E C U R I T Y A N D W E B S E R V I C E S 371
import javax.imageio.*;
import javax.swing.*;
import org.sdss.skyserver.*;
public class SkyView extends JFrame {
final static int IMAGE_WIDTH = 300;
final static int IMAGE_HEIGHT = 300;
static ImgCutoutSoap imgcutoutsoap;
public SkyView () {
super ("SkyView");
setDefaultCloseOperation (EXIT_ON_CLOSE);
setContentPane (createContentPane ());
pack ();
setResizable (false);
setVisible (true);
}
JPanel createContentPane () {
JPanel pane = new JPanel (new BorderLayout (10, 10));
pane.setBorder (BorderFactory.createEmptyBorder (10, 10, 10, 10));
final JLabel lblImage = new JLabel ("", JLabel.CENTER);
lblImage.setPreferredSize (new Dimension (IMAGE_WIDTH+9, IMAGE_HEIGHT+9));
lblImage.setBorder (BorderFactory.createEtchedBorder ());
pane.add (new JPanel () {{ add (lblImage); }}, BorderLayout.NORTH);
JPanel form = new JPanel (new GridLayout (4, 1));
final JLabel lblRA = new JLabel ("Right ascension:");
int width = lblRA.getPreferredSize ().width+20;
int height = lblRA.getPreferredSize ().height;
lblRA.setPreferredSize (new Dimension (width, height));
lblRA.setDisplayedMnemonic ('R');
final JTextField txtRA = new JTextField (25);
lblRA.setLabelFor (txtRA);
form.add (new JPanel ()
{{ add (lblRA); add (txtRA);
setLayout (new FlowLayout (FlowLayout.CENTER, 0, 5)); }});
final JLabel lblDec = new JLabel ("Declination:");
lblDec.setPreferredSize (new Dimension (width, height));
lblDec.setDisplayedMnemonic ('D');
final JTextField txtDec = new JTextField (25);
lblDec.setLabelFor (txtDec);
form.add (new JPanel ()
{{ add (lblDec); add (txtDec);
setLayout (new FlowLayout (FlowLayout.CENTER, 0, 5));}});
final JLabel lblScale = new JLabel ("Scale:");
lblScale.setPreferredSize (new Dimension (width, height));
lblScale.setDisplayedMnemonic ('S');
final JTextField txtScale = new JTextField (25);
lblScale.setLabelFor (txtScale);
form.add (new JPanel ()
{{ add (lblScale); add (txtScale);
setLayout (new FlowLayout (FlowLayout.CENTER, 0, 5));}});
final JLabel lblDO = new JLabel ("Drawing options:");
lblDO.setPreferredSize (new Dimension (width, height));
lblDO.setDisplayedMnemonic ('o');
final JTextField txtDO = new JTextField (25);
lblDO.setLabelFor (txtDO);
form.add (new JPanel ()
{{ add (lblDO); add (txtDO);
setLayout (new FlowLayout (FlowLayout.CENTER, 0, 5));}});
pane.add (form, BorderLayout.CENTER);
C H A P T E R 1 0 ■ S E C U R I T Y A N D W E B S E R V I C E S 373
final JButton btnGP = new JButton ("Get Picture");
ActionListener al;
al = new ActionListener () {
public void actionPerformed (ActionEvent e) {
try {
double ra = Double.parseDouble (txtRA.getText ());
double dec = Double.parseDouble (txtDec.getText ());
double scale = Double.parseDouble (txtScale.getText ());
String dopt = txtDO.getText ().trim ();
byte [] image = imgcutoutsoap.getJpeg (ra, dec, scale, IMAGE_WIDTH, IMAGE_HEIGHT, dopt);
lblImage.setIcon (new ImageIcon (image));
}
catch (Exception exc) {
JOptionPane.showMessageDialog (SkyView.this, exc.getMessage ());
} } };
btnGP.addActionListener (al);
pane.add (new JPanel () {{ add (btnGP); }}, BorderLayout.SOUTH);
return pane;
}
public static void main (String [] args) throws IOException {
ImgCutout imgcutout = new ImgCutout ();
imgcutoutsoap = imgcutout.getImgCutoutSoap ();
Runnable r = new Runnable () {
public void run () {
try {
String lnf;
lnf = UIManager.
getSystemLookAndFeelClassName ();
UIManager.setLookAndFeel (lnf);
}
catch (Exception e) {
}
new SkyView ();
} };
EventQueue.invokeLater (r);
} }
Listing 10-8 is largely concerned with creating SkyView’s user interface. If you are curi- ous about new JPanel () {{ add (lblImage); }}, this code subclasses javax.swing.JPanel via an anonymous inner class, creates an instance of the subclass panel, adds the speci- fied component to the instance via its object initializer, and returns the instance. (I find this and similar code to be a convenient shorthand.)
Listing 10-8 also refers to an org.sdss.skyserverpackage and its ImgCutoutand ImgCutoutSoapmember classes. This package is obtained by invoking the wsimporttool on the http://casjobs.sdss.org/ImgCutoutDR5/ImgCutout.asmx?wsdlURI to create the Image Cutout web service’s artifacts. The following command line accomplishes this task:
wsimport -keep http://casjobs.sdss.org/ImgCutoutDR5/ImgCutout.asmx?wsdl
The wsimporttool creates an orgdirectory within the current directory. This directory contains an sdsssubdirectory, which has a skyserversubdirectory. In addition to the class files for accessing Image Cutout, skyservercontains the source files (thanks to the -keep option) that describe the artifacts for accessing this web service.
The ImgCutout.javasource file shows that ImgCutoutextends javax.xml.ws.Service, which provides a client view of a web service. ImgCutout’s public ImgCutoutSoap getImgCutoutSoap()method invokes Service’s public <T> T getPort(QName portName, Class<T> serviceEndpointInterface)method to return a stub for invoking web service operations via the stub’s methods.
C H A P T E R 1 0 ■ S E C U R I T Y A N D W E B S E R V I C E S 375
SkyViewaccesses ImgCutoutSoap’s public byte[] getJpeg(double ra, double dec, double scale, int width, int height, String opt)method only. This method is invoked to return an array of bytes that describes a portion of the sky as a JPEG image. Its parame- ters are as follows:
• raand dec: Specify the center coordinates of the image in terms of right ascension and declination values (each value is specified in degrees).
■ Note The astronomical terms right ascension and declination are described by Wikipedia’s Right ascension (http://en.wikipedia.org/wiki/Right_ascension) and Declination (http://en.
wikipedia.org/wiki/Declination) entries, respectively.
• scale: Specifies a scaling value, in terms of arcseconds per pixel. One arcsecond equals 1/1296000 of a circle.
• widthand height: Identify the dimensions of the returned image.
• opt: Identifies a sequence of codes for drawing over the image. These are String codes such as the following:
• Gdraws a grid over the image.
• Llabels the image.
• Iinverts the image.
The getJpeg()method never returns a null reference. If an error occurs, the method returns an image that presents the error message.
Assuming that the current directory contains both SkyView.javaand the orgsubdirec- tory, invoke javac SkyView.javato compile this application’s source code.
Following compilation, invoke java SkyViewto run the application. Figure 10-2 shows what you will see when you specify the values that are shown in the figure’s text fields.
Figure 10-2.Viewing an image of New Galatic Catalog (NGC) 5792, a spiral galaxy seen nearly edge-on. The bright red star is located in the Milky Way galaxy.
■ Tip Check out the “Famous Places” section (http://cas.sdss.org/dr6/en/tools/places/) of the Sloan Digital Sky Survey/SkyServer site to obtain the right ascension/declination values for various astro- nomical images.