on 10-31-2006 4:20 AM
Hi,
I created sample Calculator EJB 3.0 session bean with two methods for adding and subtracting numbers. I then created an Enterprise Application project 5 and added the EJB project to it.
I generated the bottom-up web service for the EJB as has been described in the documentation. However while generating the web service i exposed only one of the methods (for adding numbers). In the source code i find that only one method has been annotated with @WebMethod.
However the WSDL that gets generated has both the methods in that. I also downloaded a SOAP UI tool (<a href="http://sourceforge.net/project/showfiles.php?group_id=136013&package_id=163662&release_id=407753">SOAP UI</a>) and tested the web service using it and i am able to call both the methods.
I am not sure if this how it should happen. If i want to just expose one of the methods i feel in the WSDL also only this method should be present.
Please give your suggestions on this.
Regards
Sidharth
Hi,
I had a somehow similar problem using Web Services. And now I have a small problem understanding the spec of the Web Service annotations. On the one hand the spec says:
<i>If the implementation bean does not implement a service endpoint interface and
there are no @WebMethod annotations in the implementation bean (excluding
@WebMethod annotations used to exclude inherited @WebMethods), all public
methods other than those inherited from java.lang.Object will be exposed as Web
Service operations, subject to the inheritance rules specified in Common
Annotations for the Java Platform [12], section 2.1.</i>
Meaning that all public methods are exposed if no WebMethod annotation is present. This would leave to the fact, that If you created a Sessionbean representing a facade and offering something like 50 methods (I know, this is a quite high number) and you only need to expose one method as a web service, you would need to annotate 49 methods with @WebService(exclude=true). And the explicit method would be left out.
On the other hand the spec references the <a href="https://sdlc2b.sun.com/ECom/EComActionServlet;jsessionid=BB6CAA208F669627979D776C6C89365E#">Common Annotations Spec</a> in Section 2.1 says:
<i>For example, a @WebService annotation on a class implies that all the public method in the class that it is applied on are annotated with @WebMethod if there is <b>no</b> @WebMethod annotation on any of the methods.</i>
For the update of the JSR 181 it was explicitly referenced to the inheritance rules specified in Common Annotations Spec, meaning that if you apply a member level annotation this would override the class level annotation.
From my point of view, this leads to the following result:
1) @WebService annotation with <b>no</b> @WebMethod -> all public methods are to be exposed (Class Level Annotation implying Member Level annotations)
2) @WebService <b>with</b> @WebMethod -> only anotated methods are to be exposed. (Member Level annotation overriding class level annotation)
If this would not be like this the JSR 181 Spec left a hole in its description by applying the Changes of Maintenance Release 1. Otherwise the default value for the exclude member in the WebMethod implementation would make no sense as well.
Would be nice to hear you thoughts on this topic.
Regards,
Martin
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello again,
another point for defining member level annotations that override the class level annotation is class inheritance. One big advantage of EJB3 is the possibility to extend beans. Now imagine the following scenario:
Define a Session Bean that provides several method with parameters that are not serializable. Now you create a facade to this class that extends this session bean and exposes itself again as a session bean. This facades now want to expose a web service. By adding a web service method and adding the @WebService annotation to the class and adding the @WebMethod to the method this should be done.
Deploying this project will fail! The reason is simple. The class level annotation for the web service has strong impact on the base class. Since the base class contains not serializable arguments the web service cannot be published. If you do not own the source code of the base class you would have to override <b>all</b> public methods of this class.
From the programmatic point of view this is not usable and I cannot imagine that this was intended by the writers of the spec. Or am I so totally wrong?
Regards Martin
Hi Martin,
In this case one should use the <b>endpointInterface</b> attribute of the <b>@WebService</b> annotation.
<i>"This annotation allows the developer to separate the interface contract from the implementation. If this annotation is present, the service endpoint interface is used to determine the abstract WSDL contract (portType and bindings). The service endpoint interface MAY include JSR-181 annotations to customize the mapping from Java to WSDL. The service implementation bean MAY implement the service endpoint interface, but is not REQUIRED to do so."</i>
Please refer to sections 3.1 and 4.1 of the Web Services Metadata MR spec.
Best regards,
Vladimir
Hello Sidhardth,
I guess that both of your methods are public?
If I am not mistaken when the methods are public they are being exposed by default. If you want to expose only one of the methods you should set the other to private for example..
Greetings,
Bobby
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Bobby,
You are right that both the methods are public. However as far as i have understood if we want to just expose a few methods we just have to annotate them with @webMethod.
Also as per the documentation it seems we can select only the methods we want to expose. This was also possible in WAS 7 i believe.
Regards
Sidharth
Here is a Quote from the <b><a href="http://jcp.org/aboutJava/communityprocess/final/jsr181/index.html">JSR-000181 Web Services Metadata for the JavaTM Platform</a></b>:
<b>4.2 Annotation: javax.jws.WebMethod </b>
<b>4.2.1 Description</b>
Customizes a method that is exposed as a Web Service operation. The WebMethod
annotation includes the following member-value pairs:
<b>Member-Value</b> - <b>operationName</b>:
<b>Meaning</b> - Name of the wsdl:operation matching this method.
<b>Default</b>- The name of the Java method
<b>Member-Value</b> - <b>Action</b>
<b>Meaning</b> - The action for this operation. For SOAP bindings, this determines the value of the SOAPAction header
<b>Default</b> - ""
<b>4.2.2 Annotation Type Definition</b>
@Retention(value=RetentionPolicy.RUNTIME)
@Target()
public @interface WebMethod {
String operationName() default "";
String action() default "" ;
};
4.2.3 Example
Java source:
@WebService
public class MyWebService {
@WebMethod(operationName = "echoString", action="urn:EchoString")
public String echo(String input) {
return input;
}
}
Resulting WSDL:
<definitions>
<portType name="MyWebService">
<operation name="echoString"/>
<input message="echoString"/>
<output message="echoStringResponse"/>
</operation>
</portType>
<binding name="PingServiceHttpSoap">
<operation name="echoString">
<soap:operation soapAction="urn:EchoString"/>
18
</operation>
</binding>
</definitions>
Hi Bobby,
I was going through that specification and on page 13 section <i>3.1 Service Implementation Bean</i> the 6th bullet mentions:
<i>If the implementation bean does not implement a service endpoint interface, all
public methods other than those inherited from java.lang.Object will be exposed
as Web Service operations. This behavior can be overridden by using the
WebMethod annotation to specify explicitly those public methods that are to be
exposed. If a WebMethod annotation is present, only the methods to which it is
applied are exposed.</i>
I feel @WebMethod should then expose method as WS operation.
What do you suggest.
Regards
Sidharth
I suggest looking at the last Maintanance Release 2.0 of the specification
<b><a href="http://jcp.org/aboutJava/communityprocess/mrel/jsr181/index.html">JSR-000181 Web Services Metadata for the Java Platform</a></b>
There on <i>3.1 Service Implementation Bean</i> on the same bullet is written:
<i>If the implementation bean does not implement a service endpoint interface and
there are no @WebMethod annotations in the implementation bean (excluding
@WebMethod annotations used to exclude inherited @WebMethods), all public
methods other than those inherited from java.lang.Object will be exposed as Web
Service operations, subject to the inheritance rules specified in Common
Annotations for the Java Platform [12], section 2.1.</i>
Furthermore at <b>4.2.1 </b> is added one more Member-Value for the WebMethod annotation:
<b>exclude</b> - Marks a method to NOT be exposed as a
web method. Used to stop an inherited
method from being exposed as part of this web service.
If this element is specified, other elements MUST NOT be specified for the @WebMethod.
<b>Default value</b> - False
Greetings,
Bobby
Hi Bobby,
Adding the exclude has not exposed the method. So that has worked.
However in the italic part mentioned it still says that if none of the methods are annotated with @WebMethod then all the methods will be exposed.
In my case one method was annotated.
Is my understanding correct.
Thanks and Regards
Sidharth
Hello Sidharth,
my understanding is that all public methods will be exposed except the ones that use annotation @WebMethod with Member-Value <b>exclude = true</b>.
The other methods that use @WebMethod but with Member-Values different from <b>exclude = true</b> will also be exposed.
Regards,
Bobby
User | Count |
---|---|
88 | |
23 | |
11 | |
9 | |
8 | |
5 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.