Version 3.1 by Pascal Robert on 2007/09/03 19:24

Show last authors
1 This documentation was written by Andrew Lindesay ([[http://www.lindesay.co.nz]]) in 2006 as part of supported code in the LEWOStuff framework, but this material has been transcribed here. It was written around the time of WebObjects 5.2 and 5.3 on the 1.4 JVM.
2
3 AXIS provides a number of handlers for ultimately executing the WS. This generally works in the WebObjects environment out of the box. However, in the case of a servlet deployment, the URLs are manipulated by the servlet container so they look something like this.
4
5 {{panel}}
6
7 ...ects/FOO.woa/ws/FooService;jsessionid=abc.i1?wsdl
8
9 {{/panel}}
10
11 If a client starts a session on a WS invocation then you want all subsequent requests to return to this same servlet container (Here we assume a redundant deployment where there are a number of servlet containers.) where the session resides. However the servlet-container's HTTP adaptor typically only knows this by looking at the modified URL. Unfortunately, the default WSDL generated by AXIS would have a section like this.
12
13 {{code}}
14
15 ...
16 <wsdl:service name="FooService">
17 <wsdl:port name="FooService" binding="impl:FooService SoapBinding">
18 <wsdlsoap:address location="http://foo.co.nz/FOO/WebObjects/FOO.woa/ws/FooService"/>
19 </wsdl:port>
20 </wsdl:service>
21 ...
22
23 {{/code}}
24
25 A WSDL like this does not contain the modified URL caused by the context having a session in the location for the service. The example handler //LEWOWebServicesWSDLLocationHandler// below which is supplied in LEWOStuff will correct the location supplied in the WSDL to contain the session information. To install this handler for use in WebObjects, locate the //server.wsdd// file within your project and modify the following section so that it appears as follows.
26
27 {{code}}
28
29 ...
30 <transport name="http">
31 <requestFlow>
32 <handler type="HTTPActionHandler"/>
33 <handler type="URLMapper"/>
34 <handler type="java:nz.co.lindesay.common.webobjects.LEWOWebServicesWSDLLocationHandler"/>
35 </requestFlow>
36 </transport>
37
38 {{/code}}
39
40 You then need to put the following class into your project.
41
42 {{code}}
43
44 package nz.co.lindesay.common.webobjects;
45
46 /*
47 ------------------------------------------------------------
48 LICENSE
49 ------------------------------------------------------------
50
51 Copyright (c) 2006, Andrew Lindesay
52 All rights reserved.
53
54 Redistribution and use in source and binary forms, with or
55 without modification, are permitted provided that the
56 following conditions are met:
57
58 * Redistributions of source code must retain the above
59 copyright notice, this list of conditions and the
60 following disclaimer.
61
62 * Redistributions in binary form must reproduce the above
63 copyright notice, this list of conditions and the
64 following disclaimer in the documentation and/or other
65 materials provided with the distribution.
66
67 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
68 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
69 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
70 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
72 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
73 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
74 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
75 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
76 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
77 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
78 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
79 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80 SUCH DAMAGE.
81
82 ------------------------------------------------------------
83 */
84
85 import com.webobjects.foundation.*;
86 import com.webobjects.appserver.*;
87
88 import org.apache.axis.*;
89
90 /**
91 * <P>This class is an AXIS request handler that is designed to
92 * manipulate the outbound WSDL that is generated for a
93 * request. The manipulation undertaken here is to modify the
94 * location of the actual service. The reason for doing this is
95 * that if you have a web service deployed into a servlet
96 * container as a WO application, the session'ed URLs can look
97 * a bit like this.</P>
98 *
99 * <P><TT>http://foo.co.nz/FOO/WebObjects/FOO.woa/ws/FooService;jsessionid=abc.i1?wsdl</TT></P>
100 *
101 * <P>However, once the URL is returned as a location for a service
102 * from AXIS, the session part at the end is removed and if you are
103 * using a multi-container deployment, the subsequent requests will
104 * not arrive at the correct servlet container.</P>
105 *
106 * <P>By installing this AXIS handler, this problem is resolved.
107 * To install it, locate the "<TT>server.wsdd</TT>" file in your
108 * WO project and add the following line to the "<I>requestFlow</I>"
109 * handler list as the last item in the list. This should be the
110 * request flow in the HTTP transport section.</P>
111 *
112 * <P><TT><handler type="java:nz.co.lindesay.common.webobjects.LEWOWebServicesWSDLLocationHandler"/></TT></P>
113 *
114 * <P>This should also work with the "<I>wotaskd</I>" deployment
115 * style as well.</P>
116 */
117
118 public class LEWOWebServicesWSDLLocationHandler extends org.apache.axis.handlers.BasicHandler
119 {
120
121 // --------------------------------------------------------------
122
123 public LEWOWebServicesWSDLLocationHandler() { super(); }
124
125 // --------------------------------------------------------------
126
127 /**
128 * <P>This is the AXIS hook where we can manipulate the outbound
129 * WSDL.</P>
130 */
131
132 public void generateWSDL(MessageContext msgContext) throws AxisFault
133 {
134 WOContext context = WOWebServiceUtilities.currentWOContext();
135 WORequest request = context.request();
136 String host = LEWOHelper.getExternalHostnameFromInboundRequest(request);
137 int port = LEWOHelper.getExternalPortFromInboundRequest(request);
138 int appi = request.applicationNumber();
139
140 if((null==host)||(0==host.length()))
141 throw new IllegalStateException("the host cannot be determined from the inbound request.");
142
143 if(context.hasSession())
144 context.session();
145
146 StringBuffer sb = new StringBuffer();
147
148 sb.append("http://");
149 sb.append(host);
150
151 if(-1!=port)
152 {
153 sb.append(":");
154 sb.append(Integer.toString(port));
155 }
156
157 String path = context.urlWithRequestHandlerKey(
158 request.requestHandlerKey(),
159 request.requestHandlerPath(),
160 null);
161
162 // Unless the context has a session, we can't get it to come back
163 // to a specific instance, but in the case of a 'wotaskd' deploy,
164 // there is no way to specify the session for a WSDL request, so
165 // we'll do a nasty hack to make this work.
166
167 if((-1!=appi)&&(!context.hasSession()))
168 {
169 String webServiceRequestHandlerKey = WOApplication.application().webServiceRequestHandlerKey();
170 String startPath = request.adaptorPrefix()+"/"+request.applicationName()+".woa"; // ''/cgi-bin/WebObjects/Foo.woa''
171
172 if(!path.startsWith(startPath))
173 throw new IllegalStateException("The path '"+path+"' should have started with '"+startPath+"'");
174
175 if(path.startsWith(startPath+"/"+webServiceRequestHandlerKey))
176 {
177 StringBuffer pathSB = new StringBuffer();
178
179 pathSB.append(startPath);
180 pathSB.append("/");
181 pathSB.append(Integer.toString(appi));
182 pathSB.append(path.substring(startPath.length()));
183
184 path = pathSB.toString();
185 }
186 }
187
188 sb.append(path);
189
190 msgContext.setProperty(MessageContext.WSDLGEN_SERV_LOC_URL,sb.toString());
191 }
192
193 // --------------------------------------------------------------
194
195 /**
196 * <P>Basically there is nothing to do here because we are not
197 * interested in messing with the request/response cycle - rather
198 * we want only to manipulate the WSDL.</P>
199 */
200
201 public void invoke(MessageContext msgContext) throws AxisFault
202 {
203 }
204
205 // --------------------------------------------------------------
206
207 }
208
209 {{/code}}
210
211 Although this is slightly crude, it should produce the correct result in the WSDL.