I have 2 questions
I am trying to run a axis 2 sample. In the last part of the instruction file, there is this line which it says, should be run in the terminal(ubuntu), is not working
java -Djava.ext.dirs=%AXIS2_HOME%\lib;%JAVA_HOME%\jre\lib\ext -cp target/classes org.apache.axis2.jaxws.addressbook.AddressBookClient.class
I am not an expert in this field, and I am not familiar with ubuntu commands. I feel that this is not an ubuntu command
The error I get is, "Invalid Job"
Can someone convert this into an ubuntu command?
Since it was not working, I built the jar using,
mvn clean install
Then I copied the jar file to the servicejars directory under repository, in axis2
Then the axis server says that the jar does not contain the WebServices annotation
"No #WebService annotated service implementations found in the jar: file:/home/dodan/Programs/axis2-1.6.0/repository/servicejars/jaxws-addressbook-1.6.0-client.jar. Service deployment failed."
So I added it to the original java file which did not have that annotation(and the import too)
Yet the axis2 server still sys that there is not webservices annotation
2. Can somebody say whether I have missed anything?
here is the java file I changed
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.jws.WebService;
import java.util.Map;
/**
* Simple JAX-WS Dispatch client for the address book service implementation.
*/
#WebService
public class AddressBookClient {
private static String NAMESPACE = "http://addressbook.jaxws.axis2.apache.org";
private static QName QNAME_SERVICE = new QName(NAMESPACE, "service");
private static QName QNAME_PORT = new QName(NAMESPACE, "port");
private static String ENDPOINT_URL = "http://localhost:8080/axis2/services/AddressBookImplService.AddressBookImplPort";
private static String ADD_ENTRY_BODY_CONTENTS =
"<ns1:addEntry xmlns:ns1=\"http://addressbook.jaxws.axis2.apache.org\">" +
"<ns1:firstName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myFirstName</ns1:firstName>" +
"<ns1:lastName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myLastName</ns1:lastName>" +
"<ns1:phone xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myPhone</ns1:phone>" +
"<ns1:street xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myStreet</ns1:street>" +
"<ns1:city xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myCity</ns1:city>" +
"<ns1:state xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myState</ns1:state>" +
"</ns1:addEntry>";
private static String FIND_BODY_CONTENTS =
"<ns1:findByLastName xmlns:ns1=\"http://addressbook.jaxws.axis2.apache.org\">" +
"<ns1:lastName xmlns=\"http://addressbook.jaxws.axis2.apache.org\">myLastName</ns1:lastName>" +
"</ns1:findByLastName>";
public static void main(String[] args) {
try {
System.out.println("AddressBookClient ...");
Service svc = Service.create(QNAME_SERVICE);
svc.addPort(QNAME_PORT, null, ENDPOINT_URL);
// A Dispatch<String> client sends the request and receives the response as
// Strings. Since it is PAYLOAD mode, the client will provide the SOAP body to be
// sent; the SOAP envelope and any required SOAP headers will be added by JAX-WS.
Dispatch<String> dispatch = svc.createDispatch(QNAME_PORT,
String.class, Service.Mode.PAYLOAD);
// Invoke the Dispatch
System.out.println(">> Invoking sync Dispatch for AddEntry");
String response = dispatch.invoke(ADD_ENTRY_BODY_CONTENTS);
System.out.println("Add Entry response: " + response);
System.out.println(">> Invoking Dispatch for findByLastName");
String response2 = dispatch.invoke(FIND_BODY_CONTENTS);
System.out.println("Find response: " + response2);
} catch (Exception e) {
System.out.println("Caught exception: " + e);
e.printStackTrace();
}
}
}
You're using Windows syntax for environment variables.
Instead of %AXIS_HOME%, you would use $AXIS_HOME.
That said, you do not need any version of Axis to learn about web services these days. JAX-WS implementations exist in the JDK for Java 6 and newer.
There's a lot of tutorials around for it.
Related
I have a class which loads an image to amazon S3 and returns public url to that image. When I run that class as Java application - everything works fine. When I create a SOAP web service from top-down approach and try to invoke that code within web service code - it fails. I know exactly where it fails, but I don't know why and also I can't debug it, doesn't print anything to console, although I'm trying catch errors.
I am getting java.lang.reflect.InvocationTargetException. I searched here and amazon forums, couldn't find any suggestions how to solve this problem (I saw many questions with this error, but no solution).
Here's my class to upload image and get url, which works good as Java application:
import java.io.File;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
public class S3Uploader {
private String url = null;
public S3Uploader(String filePath){
setUrl(s3uploadAndGetUrl(filePath));
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String s3uploadAndGetUrl(String file) {
// get access to S3
//TODO protect amazon credentials, refer to amazon documentation about proper way of providing credentials.
String result = null;
URL url;
try {
AWSCredentials awsCreds = new BasicAWSCredentials(
"myCredentials",
"myCredentials");
System.out.println("Credentials loaded.");
AmazonS3Client s3Client = new AmazonS3Client(awsCreds);
System.out.println("Client created.");
// image to upload
File image = new File(file);
// set expiration date of images' urls
Calendar origDay = Calendar.getInstance();
Calendar expirationDay = (Calendar) origDay.clone();
expirationDay.add(Calendar.DAY_OF_YEAR, 30);
Date expirationDate = expirationDay.getTime();
// set bucket and images names
String bucketName = s3Client.listBuckets().get(0).getName();
String objectKey = image.getName();
// upload image
PutObjectRequest putObject = new PutObjectRequest(bucketName,
objectKey, image);
s3Client.putObject(putObject);
// create and retrieve image url
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(
bucketName, objectKey);
generatePresignedUrlRequest.setMethod(HttpMethod.GET);
generatePresignedUrlRequest.setExpiration(expirationDate);
url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
result = url.toString();
System.out.println("Pre-Signed URL = " + url.toString());
System.out.println();
} catch (AmazonServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
result = e.getCause().getMessage();
} catch (AmazonClientException e) {
// TODO Auto-generated catch block
System.out.println(e.getCause().getMessage());
result = e.getCause().getMessage();
}
return result;
}
}
Now web service code where I invoke this class:
/**
* UrlsCreatorSOAPImpl.java
*
* This file was auto-generated from WSDL
* by the Apache Axis 1.4 Apr 22, 2006 (06:55:48 PDT) WSDL2Java emitter.
*/
public class UrlsCreatorSOAPImpl implements org.example.www.UrlsCreator.UrlsCreator_PortType{
public java.lang.String getImagesUrls(java.lang.String Url) throws java.rmi.RemoteException {
S3Uploader upload = new S3Uploader("C:/Users/Maksym/Dropbox/Greece/Matala/IMG_20140508_134143.jpg");
return upload.getUrl();
}
}
And here is the only thing that gets printed to console:
INFO: Credentials loaded.
Also SOAP request:
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://www.example.org/UrlsCreator/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <q0:GetImagesUrls>
<Url>asdasdadsa</Url>
</q0:GetImagesUrls>
</soapenv:Body>
</soapenv:Envelope>
And SOAP response:
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <soapenv:Body>
- <soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>java.lang.reflect.InvocationTargetException</faultstring>
- <detail>
<ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">Maksym-PC</ns1:hostname>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Please help if you can and let me know if I need to provide any additional info. Thanks in advance.
UPDATE 1: I downloaded java aws sdk 2-3 days ago, so it should be the latest one. Here is a list of jar files under WEB-INF/lib:
aws-java-sdk-1.7.10-javadoc.jar
aws-java-sdk-1.7.10.jar
aws-java-sdk-flow-build-tools-1.7.10.jar
axis.jar
commons-codec-1.3.jar
commons-discovery-0.2.jar
commons-logging-1.1.1.jar
commons-logging.jar
httpclient-4.2.3.jar
httpcore-4.2.jar
jackson-annotations-2.1.1.jar
jackson-core-2.1.1.jar
jackson-databind-2.1.1.jar
jaxrpc.jar
joda-time-2.2.jar
saaj.jar
wsdl4j.jar
SOLUTION: as it turned out - the problem was with glassfish or just my laptop, I don't know. I tried from scratch on another laptop, with the same eclipse version, same glassfish and it worked, I still don't know what was wrong with my laptop (other webservices run smoothly, cleaning projects and server didn't help either).
Anyway, thanks for trying to help =)
Ensure that you're using the same library API version when running the code as you were when developing/compiling your code. And in the case of the remote S3 API, make sure that the version you have on the client side is compatible with the server side version.
I am copying the simplest web service example from CXF; it steps through writing an interface, then an implementation file, to say hello to a name provided by the webservice consumer. I changed a package name and the method name because I wanted to see where things showed up; if you name everything HelloWorld you can't see what is method, package, class, etc.
Those instructions include a program to publish the web service. After I do that, putting the URL
http://localhost:9000/helloWorld?wsdl
in a browser displays a wsdl file that contains enough stuff the way I spelled it to convince me that it was generated from my code. I assume, based on this, that both the WSDL generation and the publication worked.
This is the service interface:
package hw;
import javax.jws.WebParam;
import javax.jws.WebService;
#WebService
public interface HelloWorld
{
String sayHi(#WebParam(name="firstName") String firstName);
}
This is the service implementation:
package hwimpl;
import javax.jws.WebService;
#WebService(endpointInterface = "hw.HelloWorld", serviceName = "HelloWorld")
public class HelloWorldImpl
{
static public void say(String msg) { System.out.println(msg); }
public String sayHi(String firstName)
{ say ("sayHi called with " + firstName);
return "Hello " + firstName + " from the World.";
}
}
And this is the publishing program:
package hwimpl;
import javax.xml.ws.Endpoint;
public class PublishHelloWorldService
{
protected PublishHelloWorldService() throws Exception
{
// START SNIPPET: publish
System.out.println("Starting Server");
HelloWorldImpl implementor = new HelloWorldImpl();
String address = "http://localhost:9000/helloWorld";
Endpoint.publish(address, implementor);
// END SNIPPET: publish
}
public static void main(String args[]) throws Exception
{
new PublishHelloWorldService();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
Now I compile and run this program:
package client;
import hw.HelloWorld;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
public final class HelloWorldClient
{
private static final QName SERVICE_NAME = new QName("http://server.hw.demo/", "HelloWorld");
private static final QName PORT_NAME = new QName("http://server.hw.demo/", "HelloWorldPort");
private HelloWorldClient()
{
}
public static void main(String args[]) throws Exception
{
Service service = Service.create(SERVICE_NAME);
String endpointAddress = "http://localhost:9000/helloWorld";
// If web service deployed on Tomcat deployment, endpoint should be changed
// to:
// String
// endpointAddress =
// "http://localhost:8080/java_first_jaxws/services/hello_world";
// Add a port to the Service
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
HelloWorld hw = service.getPort(HelloWorld.class);
System.out.println(hw.sayHi("Albert"));
}
}
and I get this error:
Exception in thread "main" javax.xml.ws.WebServiceException: Could not send Message.
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
at com.sun.proxy.$Proxy20.sayHi(Unknown Source)
at client.HelloWorldClient.main(HelloWorldClient.java:37)
Caused by: java.net.MalformedURLException: Invalid address. Endpoint address cannot be null.
at org.apache.cxf.transport.http.HTTPConduit.getURL(HTTPConduit.java:872)
at org.apache.cxf.transport.http.HTTPConduit.getURL(HTTPConduit.java:854)
at org.apache.cxf.transport.http.HTTPConduit.setupURL(HTTPConduit.java:800)
at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:548)
at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:313)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:265)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
... 2 more
I am running the programs -- both publish and client -- from eclipse. The eclipse is set up with proxies for http and https in Window / Preferences; I removed the one for http before running the client, but it did not change the message.
It is in fact a tomcat server; I tried the alternate URL in the publish program with no change.
I don't run tomcat from within eclipse in this case; I run it by itself on my machine and then run the publish program (from eclipse), verify the url that displays the wsdl works correctly, and then run the client program (from eclipse) and get my error.
Can someone tell me what I'm doing wrong? I've seen other posts on this exact error message, but none of the answers were definitive and I appear to have tried them all.
Not sure this is your problem.
I've sometimes had problems with eclipse not being able to run tomcat applications on a running tomcat as you describe in your example.
What I sometimes have to do when working with tomcat and eclipse is either
have a running tomcat (windows service) and then export my eclipse application to that tomcat
stop the running tomcat on that port from windows services and start the tomcat from inside eclipse when running the program.
For some reason eclipse seems to have problems with an already running tomcat.
I'm in the process of making a proof of concept to dissociate the business code from the gui for the ps3 media server (http://www.ps3mediaserver.org/). For this I've got a project hosted at source forge (http://sourceforge.net/projects/pms-remote/). The client should be a simple front end to configure the server from any location within a network having the rights to connect to the server.
On the server side, all service have been exposed using javax.jws and the client proxy has been generated using wsimport.
One of the features of the current features (actually, the only blocking one), is to define the folders that will be shared by the server. As the client and server are now running as a single application on the same machine, it's trivial to browse its file system.
Problem: I'd like to expose the file system of the server machine through web services. This will allow any client (the one I'm currently working on is the same as the original using java swing) to show available folders and to select the ones that will be shown by the media server. In the end the only thing I'm interested in is an absolute folder path (string).
I thought I'd find a library giving me this functionality but couldn't find any.
Browsing the files using a UNC path and accessing a distant machine doesn't seem feasible, as it wouldn't be transparent for the user.
For now I don't want to worry about security issues, I'll figure these out once the rest seems feasible.
I'd be grateful for any input.
Thanks, Philippe
I've ended up creating a pretty simple web service letting either list all root folders or all child folders for a given path.
It's now up to the client to have a (GUI) browser to access this service.
package net.pms.plugin.webservice.filesystem;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import net.pms.plugin.webservice.ServiceBase;
#WebService(serviceName = "FileSystem", targetNamespace = "http://ps3mediaserver.org/filesystem")
public class FileSystemWebService extends ServiceBase {
#WebMethod()
public List<String> getRoots() {
List<String> roots = new ArrayList<String>();
for(File child : File.listRoots()) {
roots.add(child.getAbsolutePath());
}
return roots;
}
#WebMethod()
public List<String> getChildFolders(#WebParam(name="folderPath") String folderPath) throws FileNotFoundException {
List<String> children = new ArrayList<String>();
File d = new File(folderPath);
if(d.isDirectory()) {
for(File child : d.listFiles()) {
if(child.isDirectory() && !child.isHidden()) {
children.add(child.getAbsolutePath());
}
}
} else {
throw new FileNotFoundException();
}
return children;
}
}
For people wanting to use this, here's the ServiceBase class as well
package net.pms.plugin.webservice;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
public abstract class ServiceBase {
private static final Logger log = Logger.getLogger(ServiceBase.class);
protected boolean isInitialized;
/**
* the published endpoint
*/
private Endpoint endpoint = null;
/**
*
* Start to listen for remote requests
*
* #param host ip or host name
* #param port port to use
* #param path name of the web service
*/
public void bind(String host, int port, String path) {
String endpointURL = "http://" + host + ":" + port + "/" + path;
try {
endpoint = Endpoint.publish(endpointURL, this);
isInitialized = true;
log.info("Sucessfully bound enpoint: " + endpointURL);
} catch (Exception e) {
log.error("Failed to bind enpoint: " + endpointURL, e);
}
}
/**
* Stop the webservice
*/
public void shutdown() {
log.info("Shut down " + getClass().getName());
if (endpoint != null)
endpoint.stop();
endpoint = null;
}
}
From the client, you might be able to leverage the output of smbclient -L. On the server, a suitable servlet might do.
I have a interesting problem.
When I started glassfish server, everythings work fine. But, I changed some code and published the server, and I run my client (SistemGirisClientKullaniciDogrula). The application throws this exception:
java.lang.ClassCastException: tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.
Interesting part is, after the Glassfish server restart, application works fine.
I am using restlet-spring-hibernate. And I am also using JAXB (org.restlet.ext.jaxb.jar) for converting XML to Java objects. My application server is Glassfish v3.0
detail for congiguration
restlet 2.0.5
spring 3.0.5
hibernate 3.3.2
glassfish v3.0
client class(Just for test)
import java.io.IOException;
import org.restlet.Client;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.MediaType;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.ext.jaxb.JaxbRepresentation;
public class SistemGirisClientKullaniciDogrula {
public static void main(String[] Args) throws IOException {
String url = "http://localhost:8080/Project/sistemgirisws";
Client client = new Client(Protocol.HTTP);
Kullanici kullanici = new Kullanici();
kullanici.setKodu("1");
JaxbRepresentation<Kullanici> jaxbRepresentationSendingKullanici= new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);
Request request = new Request(Method.GET, url, jaxbRepresentationSendingKullanici);
Response response = client.handle(request);
JaxbRepresentation<Kullanici> kullaniciResponse = new JaxbRepresentation<Kullanici>(response.getEntity(), Kullanici.class);
kullanici = kullaniciResponse.getObject();
System.out.println("kullanici id : " + kullanici.getId());
}
}
Web Service
public class ProjectWebService {
/**
*
* #param representation
* #return
*/
#Get
public Representation getKullanici(Representation representation) {
JaxbRepresentation<Kullanici> jaxbRepresentation = new JaxbRepresentation<Kullanici>(representation, Kullanici.class);
Kullanici kullanici = new Kullanici();
try {
kullanici = jaxbRepresentation.getObject(); //THIS LINE THROW java.lang.classCastException tr.com.app.Kullanici cannot be cast to tr.com.app.Kullanici.
} catch (IOException e) {
e.printStackTrace();
}
try {
kullanici = sistemGirisBusinessManager.kullaniciDogrula(kullanici);
getResponse().setStatus(Status.SUCCESS_OK);
return new JaxbRepresentation<Kullanici>(MediaType.APPLICATION_XML, kullanici);
} catch (Exception exception) {
exception.printStackTrace();
getResponse().setStatus(Status.CLIENT_ERROR_EXPECTATION_FAILED);
return new JaxbRepresentation<MesajList>(MediaType.APPLICATION_XML, sistemGirisBusinessManager.getMesajList());
}
}
}
Does Anyone know what the problem is?
This could be a class loading issue. In Java, If two classloaders have loaded the same class, then it is treated as two different classes. In that case, your casting will fail because it seems to the JVM that you are casting one type to another which is not in an inheritance tree.
What must be happening is that when you modify your class, it gets loaded into a different classloader, where as the web service uses the original one.
Problem indeed in different class loaders. i've had it too and adding implements Serializable and serialVersionUID for those object solved the problem.
After many hours of tinkering and reading the whole internet several times I just can't figure out how to sign requests for use with the Product Advertising API.
So far I managed to generate a client from the provided WSDL file. I used a tutorial by Amazon for this. You can find it here:
Tutorial for generating the web service client
So far no problems. To test the client I wrote a small piece of code. The code is intended to simply get some information about a product. The product is specified by its ASIN.
The code:
package client;
import com.ECS.client.jax.AWSECommerceService;
import com.ECS.client.jax.AWSECommerceServicePortType;
import com.ECS.client.jax.ItemLookup;
import com.ECS.client.jax.ItemLookupResponse;
import com.ECS.client.jax.ItemLookupRequest;
public class Client {
public static void main(String[] args) {
System.out.println("API Test startet");
AWSECommerceService service = new AWSECommerceService();
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemLookupRequest itemLookup = new ItemLookupRequest();
itemLookup.setIdType("ASIN");
itemLookup.getItemId().add("B000RE216U");
ItemLookup lookup = new ItemLookup();
lookup.setAWSAccessKeyId("<mykeyishere>");
lookup.getRequest().add(itemLookup);
ItemLookupResponse response = port.itemLookup(lookup);
String r = response.toString();
System.out.println("response: " + r);
System.out.println("API Test stopped");
}
}
As you can see there is no part where I sign the request. I have worked my way through a lot of the classes used and found no methods for signing the request.
So, how to sign a request?
I actually found something in the documentation: request authentication
But they don't use their own API. The proposed solutions are more or less for manual use only. So I looked in the client classes to sort out if I could get the request URL and put all the parts needed for request signing in myself. But there are no such methods.
I hope someone can point out what I am doing wrong.
This is what I did to solve the problem. All the credit goes to Jon and the guys of the Amazon forums.
Before I outline what I did, here is a link to the post which helped me to solve the problem: Forum Post on Amazon forums.
I downloaded the awshandlerresolver.java which is linked in the post. Than I modified my own code so it looks like this:
package client;
import com.ECS.client.jax.AWSECommerceService;
import com.ECS.client.jax.AWSECommerceServicePortType;
import com.ECS.client.jax.ItemLookup;
import com.ECS.client.jax.ItemLookupResponse;
import com.ECS.client.jax.ItemLookupRequest;
public class Client {
public static void main(String[] args) {
System.out.println("API Test startet");
AWSECommerceService service = new AWSECommerceService();
service.setHandlerResolver(new AwsHandlerResolver("<Secret Key>")); // important
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemLookupRequest itemLookup = new ItemLookupRequest();
itemLookup.setIdType("ASIN");
itemLookup.getItemId().add("B000RE216U");
ItemLookup lookup = new ItemLookup();
lookup.setAWSAccessKeyId("<Access Key>"); // important
lookup.getRequest().add(itemLookup);
ItemLookupResponse response = port.itemLookup(lookup);
String r = response.toString();
System.out.println("response: " + r);
System.out.println("API Test stopped");
}
}
The println on the end are more or less useless. But it works. I also used the WSDL Jon linked to generate a new webservice client. I just changed the URLs in the tutorial I posted in my question.
Try this afer you create the service
service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));
You'll need this class and this jar file to add as a reference to your project as AwsHandlerResolver uses Base64 encoding.
You'll need to rename the AwsHandlerResolver file to the name of the class as the file name is all lower case.
I think the rest of the code you have is fine.
The WSDL is http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl
This discussion and the related Amazon post helped me get the client working. That being said, I felt that the solution could be improved with regards to the following:
Setting WebService handlers in code is discouraged. A XML configuration file and a corresponding #HandlerChain annotation are recommended.
A SOAPHandler is not required in this case, LogicalHandler would do just fine. A SOAPHandler has more reach than a LogicalHandler and when it comes to code, more access is not always good.
Stuffing the signature generation, addition of a Node and printing the request in one handler seems like a little too much. These could be separated out for separation of responsibility and ease of testing. One approach would be to add the Node using a XSLT transformation so that the handler could remain oblivious of the transformation logic. Another handler could then be chained which just prints the request.
Example
i did this in spring it's working fine.
package com.bookbub.application;
import com.ECS.client.jax.*;
import com.ECS.client.jax.ItemSearch;
import javax.xml.ws.Holder;
import java.math.BigInteger;
import java.util.List;
public class TestClient {
private static final String AWS_ACCESS_KEY_ID = "AI*****2Y7Z****DIHQ";
private static final String AWS_SECRET_KEY = "lIm*****dJuiy***YA+g/vnj/Ix*****Oeu";
private static final String ASSOCIATE_TAG = "****-**";
public static void main(String[] args) {
TestClient ist = new TestClient();
ist.runSearch();
}
public void runSearch()
{
AWSECommerceService service = new AWSECommerceService();
service.setHandlerResolver(new AwsHandlerResolver(AWS_SECRET_KEY));
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemSearchRequest request = new ItemSearchRequest();
request.setSearchIndex("Books");
request.setKeywords("java web services up and running oreilly");
ItemSearch search = new ItemSearch();
search.getRequest().add(request);
search.setAWSAccessKeyId(AWS_ACCESS_KEY_ID);
Holder<OperationRequest> operation_request =null;
Holder<List<Items>> items = new Holder<List<Items>>();
port.itemSearch(
search.getMarketplaceDomain(),
search.getAWSAccessKeyId(),
search.getAssociateTag(),
search.getXMLEscaping(),
search.getValidate(),
search.getShared(),
search.getRequest(),
operation_request,
items);
java.util.List<Items> result = items.value;
BigInteger totalPages = result.get(0).getTotalResults();
System.out.println(totalPages);
for (int i = 0; i < result.get(0).getItem().size(); ++i)
{ Item myItem = result.get(0).getItem().get(i);
System.out.print(myItem.getASIN());
System.out.print(", ");
System.out.println(myItem.getDetailPageURL());
System.out.print(", ");
System.out.println(myItem.getSmallImage() == null ? "" : myItem.getSmallImage().getURL());
}
}
}
You could achieve the same monetization outcomes with the IntentBrite API as well