I'm using IntelliJ IDEA 8 and Axis to set up a webservice that's deployed on Tomcat5.5. The generated wsdl looks like this: http://track.priskick.se/Tracker.wsdl
A method is declared as
public void storeImpressionReport(int siteId, int adId, int zoneId, int count,
int excludeCount) { ... }
and exposed in the webservice. Next, I build the client (also Java) using Axis, but as a runtime call to the method is made with the parameters 0,0,0,0,0, I get this:
Tried to invoke method public void com.xxxxx.xxxx.xxxx.xxxxx.storeImpressionReport(int,int,int,int,int) with arguments java.lang.Integer,null,null,null,null. The arguments do not match the signature.; nested exception is: java.lang.IllegalArgumentException
Reducing the number of parameters of the method to 1 makes it work, however this feels like a pretty silly limitation and strange behaviour. Please help me if you know what might be wrong here - why can't I expose methods and have them take more than one parameter?
=== UPDATE
I now tried generating the client java using wsdl generated from IntelliJ instead of calling the service with the ?wsdl option. This wsdl keeps the correct parameter names, maybe because the generator has access to the source. Now I get
No such operation 'siteId'
AxisFault
These are the relevant files:
http://track.priskick.se/Tracker/TrackerSoapBindingStub.java
http://track.priskick.se/Tracker/TrackerServiceTestCase.java
http://track.priskick.se/Tracker/Tracker_PortType.java
http://track.priskick.se/Tracker/TrackerService.java
http://track.priskick.se/Tracker/TrackerServiceLocator.java
the wsdl used for the client is found at
http://track.priskick.se/Tracker.wsdl
the service is found at
http://stage.klikki.com/services/Tracker
Cheers
Marcus Johansson
Oh the joy. I changed the service style to WRAPPED, and this seems to have solved the problem.
Related
I have a Bean class that implements an interface. The Bean has several methods with some of them returning List<...>. The Web Service call is working for all the methods which does not return List. However I get a soap fault string when i try to invoke the method which returns List .
Here is my interface
#WebService
public interface Cart {
#WebMethod(operationName="getOptionsData")
public List<OptionsData> getOptionsData(int id,int searchYear);
}
Bean Class
#WebService
public Class CartBean implements Cart {
#WebMethod(operationName="getOptionsData")
public List<OptionsData> getOptionsData(int id,int searchYear) {
return List<...>;
}
}
When i try to invoke this using my web service , i get the following response message.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>A Java method was not found for the operation. If the
WSDL operation name is different from the Java method name,
make sure that the #WebMethod annotation name is present
</faultstring>
<detail />
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
I have added both the annotations to my implementation class. However i dont understand why is it that only the method which returns List<...> and which takes parameters is not getting recognised.Methods which return List<..> with empty parameters is getting recognised and I am getting the response as expected.Is it that SOAP cannot handle Lists or is there anything wrong with the way i have implemented it? Somebody help me with this..
Thanks in advance !!
SOAP definitely can handle List<>. I have working SOAP WebService implementations that returns List<>.
Problem is maybe in specification of your methods params.
Try to annotate your parameters like this:
...
import javax.jws.WebParam;
...
#WebMethod(operationName="getOptionsData")
public List<OptionsData> getOptionsData(#WebParam(name = "id")int id,
#WebParam(name = "searchYear")int searchYear);
UPDATE
It' probably not supported by obsolete JAX-RPC. You should probably try to update to JAX-WS. You can follow tutorial below.
http://www.myeclipseide.com/documentation/quickstarts/webservices_jaxws/
UPDATE
Tutorial for eclipse Indigo.
http://www.softwareagility.gr/index.php?q=node/29
I was able to solve the problem myself. Looks like SOAP cannot handle generics. Simple thing i did was to remove the generics and use just List. And my problem got solved
You can get a JSON from your List and send the array of bytes of the JSON's file.
And in the calling method you get that array of bytes, create a temp file (if it's necessary), get the List from the JSON's file.
I do this is my application between Android and Java, and it's working fast than send the Object, because I zip the file too.
[]s
William Bertan
This question already has answers here:
JAX-RS: Multiple paths
(4 answers)
Closed 2 years ago.
Can we have more than one #Path annotation for same REST method i.e. the method executed is the same, but it is executed on accessing more than one URL?
E.g.: I want to run the searchNames() method on both http://a/b/c and http://a/b.
You can't have mutliple #Path annotations on a single method. It causes a "duplicate annotation" syntax error.
However, there's a number of ways you can effectively map two paths to a method.
Regular expressions in #Path annotation
The #Path annotation in JAX-RS accepts parameters, whose values can be restricted using regular expressions.
This annotation:
#Path("a/{parameter: path1|path2}")
would enable the method to be reached by requests for both /a/path1 and /a/path2. If you need to work with subpaths, escape slashes: {a:path1\\/subPath1|path2\\/subPath2}
Serving responses with a redirection status code
Alternatively, you could set up a redirection. Here's a way to do it in Jersey (the reference implementation of JAX-RS), by defining another subresource. This is just an example, if you prefer a different way of handling redirections, feel free to use it.
#Path("basepath")
public class YourBaseResource {
//this gets injected after the class is instantiated by Jersey
#Context
UriInfo uriInfo;
#Path("a/b")
#GET
public Responce method1(){
return Response.ok("blah blah").build();
}
#Path("a/b/c")
#GET
public Response method2(){
UriBuilder addressBuilder = uriInfo.getBaseUriBuilder();
addressBuilder.path("a/b");
return Response.seeOther(addressBuilder.build()).build();
}
}
Using a servlet filter to rewrite URLs
If you're going to need such functionality often, I suggest intercepting the incoming requests using a servlet filter and rewriting the paths on the fly. This should help you keep all redirections in one place. Ideally, you could use a ready library. UrlRewriteFilter can do the trick, as long as you're fine with a BSD license (check out their google code site for details)
Another option is to handle this with a proxy set up in front of your Java app. You can set up an Apache server to offer basic caching and rewrite rules without complicating your Java code.
As explained in Tom's answer, you can not use more than one #Path annotation on a single method, because you will run into error: duplicate annotation at compile time.
I think the simplest way to get around this is to use method overloading:
#Path("{foo}")
public Response rest(#PathParam("foo") final String foo) {
return this.rest(foo, "");
}
#Path("{foo}/{bar}")
public Response rest(#PathParam("foo") final String foo,
#PathParam("bar") final String bar) {
return Response.ok(foo + " " + bar).build();
}
You could also use more different method names if you run into the case where multiple overloaded methods have the signature.
Another solution for your particular example:
http://a/b/c
http://a/b
Let's suppose that:
/a is for the resource class
/b/c and /b are the paths for the methods
because a full path looks like:
<protocol><host><port><app><url-pattern><resource-path><method-path>.
Use optional parameter
#Path("/b{c : (/c)?}")
public Response searchNames(#PathParam("c") String val) {
...
}
The example above works for all examples like:
/b
/b/
/b/c
/b/c/
but when c is provided, the val is /c (it has a / before).
If you want to fix the problem above (to avoid Java parsing), you need something more complex:
#Path("/b{slash : (/)?}{c:((?<=/).*)?}")
which will return only c (not /c) for the 3rd bullet point, but for the 4th bullet point it will return c/ which has to be parsed in Java.
But for your case ("the method executed is the same"), don't worry about parsing because you don't have different actions.
If you are using Spring then try
#RequestMapping(value = {"/def", "/abc"}, method = RequestMethod.POST)
This will work for both /abc and /def.
– sSaroj Nov 17 '17 at 10:13
I seem to be having an issue with Java and NetBeans when it comes to writing web services.
I have searched for a couple of days with no luck, finding people with the same issue as me with zero replies.
I have created a web service which returns a complex type (LoginReply), and that complex type contains an array of another complex type (AppInfo)
However when I generate the WSDL from this, the complex type definition in the XSD is blank, and manually adding the information still makes the web service return null even when data is successfully passed to the web service.
<xs:complexType name="appInfo">
<xs:sequence/>
</xs:complexType>
LoginReply: http://pastebin.com/Umx6ayvi
AppInfo: http://pastebin.com/566WnZ4H
If anyone could point out what I'm doing wrong, or if this is a bug with NetBeans, I'm new to Java so I can't rule out that I'm simply not understanding something, but I'm close to pulling my hair out here.
EDIT:
Just noticed when i deploy to tomcat via NetBeans I get the following error:
WARNING: duplicate class definition bug occured? Please report this : uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;
java.lang.ClassFormatError: Illegal class name "uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;" in class file uk/co/example/ComplexTypes/LoginReply$JaxbAccessorM_getApplications_setApplications_[Luk_co_example_ComplexTypes_AppInfo;
Notice the random L before co_uk_example. My research suggests this is an old bug that should be fixed, and that no one else has reported this issue in over a year, no sure where to go from here.
Another edit:
Just added a new web method on the service that simply gets a list of appInfo and returns it to the client. This still fails the same way with NetBeans refusing to generate a sequence inside AppInfo.
I'm sure I'm missing something to declare the class, but I have checked it countless times to ensure I'm not missing anything.
warning gives you good hint: "WARNING: duplicate class definition bug occured"
your ws implementation class directly uses LoginReply class which directly uses AppInfo (+you are maybe also directly using this class in your ws implementation) => jaxb finds it
#XMLSeeAlso(...) tells jaxb to "link" referenced class
=> two definitions of the same class (not sure if it is by design or a bug that jaxb is not able to handle this case more gracefully)
to fix this just remove #XmlSeeAlso from your LoginReply class and you should be fine
This Issue came down to a very simple mistake. The AppInfo class was using non-standard getters and setters.
public void SetAppID(int AppID)
{
this.AppID = AppID;
}
This is INCORRECT (notice the capital on the Set), it should be:
public void setAppID(int AppID)
{
this.AppID = AppID;
}
Using a capital is not standard for JavaBeans and as such JAX-WS didn't know how to generate WSDL for this class. Thanks too shyam from the following link for answering the question
How to return a custom complex type in JAX-WS web services?
I don't think you can send "complex types" over the net (programmed port types) in http protocol, however an array may be implicitly converted to a delimited string set , check the docs for data transfer.
I am developing a Axis2 based WebServices with XMLBeans binding. I have generated the code by using WSDL2Java generator and tried testing it with sample values set in the request.
In one of the setter methods (auto-generated code) I found the below code. The method get_store() returns a null value and hence I get a NullPointerException.
target = (org.apache.xmlbeans.SimpleValue)
get_store().find_element_user(TRANSACTIONTYPE$0, 0);
I tried Google to find the solution and found similar issue with no solution specified.
Is there any work around for this issue?? Kindly help me
This issue got resolved!!
I was actually trying to instantiate a response object in a normal Java way and hence i got the above mentioned exception while running my WebServices.
Wrong way - ResponseType responseType = new ResponseType();
Correct way - ResponseType responseType = ResponseType.Factory.newInstance();
I am writing an eclipse plug-in which generates code. I am leveraging eclipse jdt to gen out classes, fields, and methods. One of the requirements I have is to generate methods with annotated paramaters...
public returnType foo(#someAnnotation int id)
{
.....
.....
}
Does anybody know how to write out the #someAnnotation using JDT? To write out normal parameters in JDT you could do something like the following
Signature.createTypeSignature("int", false)
Have you tried debugging the creation of a type signature with an annotation and inspect the parameters passed to createTypeSignature?
Yes I have tried this. The createTypeSignature() function does validation on the String that is passed to it. When it sees something like the following it throws an exception...
Signature.createTypeSignature("#PathParam(\"custId\") int");
Hope this clears it up, and thanks for the response. Let me know if you have any other ideas.