The Source for Java Technology Collaboration
User: Password:



Marc Hadley's Blog

January 2006 Archives


Printing to an Apple Airport Connected USB Printer from Solaris

Posted by mhadley on January 30, 2006 at 09:39 AM | Permalink | Comments (0)

The first thing to do is work out the IP address of the Airport base station to which you've hooked up the printer. The Airport Admin utility on a Mac can help out here if you have multiple base stations but if you have only one then its likely to the same IP address that is your default gateway. To find the default gateway type (the # represents the shell prompt, don't type it):

# netstat -rn

and look for the 'default' entry.

To make sure you've got the right IP address try:

# telnet ipaddr 9100

where ipaddr is the IP address of the base station. If telnet connects then you're probably on the right track.

Next you need to configure a Solaris printer queue that points to the networked printer. It turns out that the Airport base station works pretty much the same as a HP JetDirect print server and the following commands get the job done:

# lpadmin -p hp -v /dev/null -m netstandard -o dest=airport:9100 -o protocol=tcp -o banner=never -T PS -I postscript
# enable hp
printer "hp" now enabled
# accept hp
destination "hp" now accepting requests
# lpadmin -d hp

where hp is the name of the printer queue and airport is the IP address or DNS name of the base station. The first line creates the queue, the second and third enable the queue and set it to accept requests and the final line sets this new queue to be the default printer queue. The first line will need adjusting if you are using anything other than a PostScript printer, the key parts of the command are use of tcp for protocol rather than bsd and using TCP port 9100 on the base station.



RESTful Web Services with JAX-WS

Posted by mhadley on January 10, 2006 at 01:58 PM | Permalink | Comments (7)

The JAX-WS implementation that is included in the, recently released, JWSDP 2.0 preview now supports the XML/HTTP binding. This new functionality allows JAX-WS applications to implement and use RESTful Web services. Here is a worked example that demonstrates how to use JAX-WS to query the Yahoo News Search service.

The first step is to create a JAX-WS port for the Yahoo News Search service

URI nsURI = new URI("urn:yahoo:yn");
QName serviceName = new QName("yahoo",nsURI.toString());
QName portName = new QName("yahoo_port",nsURI.toString());
Service s = Service.create(serviceName);
URI address = new URI("http", null, "api.search.yahoo.com", 80,
    "/NewsSearchService/V1/newsSearch",
    "appid=jaxws_restful_sample&type=all&results=10&sort=date&language=en&query=java",
    null);
s.addPort(portName, HTTPBinding.HTTP_BINDING, address.toString());

Note that the URI constructed above contains a set of input parameters to the search service. The appid parameter identifies the application to Yahoo, if you are writing a new application you should register a new ID for it here. In this instance we are creating a URI that will search for news about Java and return at most 10 English language results sorted by date. Note that its not necessary to create a new port each time you change the arguments, more on that at the end.

Once the port is created we can use the Service instance to create a Dispatch instance. Dispatch is a new JAX-WS interface designed with dynamic, document-oriented services in mind. Note that it is a generic interface, in this instance we create a Dispatch<Source> instance since we are working with simple XML documents. You can also create Dispatch<SOAPMessage> instances when exchanging SOAP-based messages and Dispatch<DataHandler> for working with arbitrary types of data.

Dispatch<Source> d = s.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
Map<String, Object> requestContext = d.getRequestContext();
requestContext.put(MessageContext.HTTP_REQUEST_METHOD, new String("GET"));

Now that we have a Dispatch instance we can send the search request and retrieve the results. In this case we retrieve the results and transform them into a DOM tree.

Source result = d.invoke(null);
DOMResult domResult = new DOMResult();
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(result, domResult);

Now we have the results as a DOM tree we can apply XPath queries to extract the data we are interested in. Here we first use an XPath query to obtain the number of search results returned and then use that knowledge to interate through the results using additional queries.

XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
xp.setNamespaceContext(new NSResolver("yn", nsURI.toString()));
NodeList resultList = (NodeList)xp.evaluate("/yn:ResultSet/yn:Result", domResult.getNode(),
    XPathConstants.NODESET);
int len = resultList.getLength();
for (int i=1;i<=len;i++) {
    String title = xp.evaluate("/yn:ResultSet/yn:Result["+i+"]/yn:Title", domResult.getNode());
    String click = xp.evaluate("/yn:ResultSet/yn:Result["+i+"]/yn:ClickUrl", domResult.getNode());
    System.out.printf("[%d] %s (%s)\n",i,title,click);
}

The NSResolver class in the above is a custom class based on an example I found here. It simply maps the yn namespace prefix used in the XPath queries to the Yahoo namespace URI (urn:yahoo:yn) used in the result XML document.

I mentioned above that there's no need to create a new JAX-WS port when the input data changes, the following lines submit a new query using the existing objects we've already created.

requestContext.put(MessageContext.QUERY_STRING,
    "appid=jaxws_restful_sample&type=all&results=10&sort=date&language=en&query=solaris");
result = d.invoke(null);

That's it for now, in future blogs I'll demonstrate how to use JAXB instead of the XPath APIs to get strongly typed access to the results and how WADL can be used to generate JAX-WS based stubs for RESTful services.





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds