1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package no.feide.moria.servlet.soap;
22
23 import java.io.ByteArrayOutputStream;
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.rmi.RemoteException;
27
28 import javax.servlet.RequestDispatcher;
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import no.feide.moria.log.MessageLogger;
34
35 import org.apache.axis.AxisEngine;
36 import org.apache.axis.AxisFault;
37 import org.apache.axis.Constants;
38 import org.apache.axis.Message;
39 import org.apache.axis.MessageContext;
40 import org.apache.axis.handlers.soap.SOAPService;
41 import org.apache.axis.transport.http.AxisHttpSession;
42 import org.apache.axis.transport.http.AxisServlet;
43 import org.apache.axis.transport.http.HTTPConstants;
44 import org.apache.axis.transport.http.ServletEndpointContextImpl;
45 import org.apache.xml.serialize.XMLSerializer;
46 import org.w3c.dom.Document;
47
48 /***
49 * @author Bjørn Ola Smievoll <b.o@smievoll.no>
50 * @version $Revision: 1.7 $
51 */
52 public final class SimpleAxisServlet
53 extends AxisServlet {
54
55 /***
56 * Serial version UID.
57 */
58 private static final long serialVersionUID = 6202683940363529171L;
59
60 /***
61 * Logger for this class.
62 * */
63 private MessageLogger messageLogger = new MessageLogger(SimpleAxisServlet.class);
64
65
66 /***
67 * Default constructor.
68 */
69 public SimpleAxisServlet() {
70
71 super();
72 }
73
74
75 /***
76 * Initializes the servlet. Called by the container.
77 * @throws ServletException
78 * If unable to initialize the servlet.
79 */
80 public void init() throws ServletException {
81
82 super.init();
83 }
84
85
86 /***
87 * Handles HTTP GET requests. As SOAP uses POST, this basically returns a
88 * empty page.
89 * @param request
90 * The incoming HTTP request object.
91 * @param response
92 * The outgoing HTTP reponse object.
93 */
94 public void doGet(final HttpServletRequest request, final HttpServletResponse response) {
95
96
97 if (request == null) {
98 messageLogger.logCritical("Response object cannot be null", new NullPointerException("request is null"));
99 return;
100 }
101
102 if (response == null) {
103 messageLogger.logCritical("Response object cannot be null", new NullPointerException("response is null"));
104 return;
105 }
106
107
108 AxisEngine axisEngine = null;
109
110
111 SOAPService service = null;
112
113
114 PrintWriter printWriter = null;
115
116
117 try {
118 printWriter = response.getWriter();
119 } catch (IOException ioe) {
120 handleException("Unable to get response writer", ioe, request, response);
121 return;
122 }
123
124
125 try {
126 axisEngine = getEngine();
127 } catch (AxisFault fault) {
128 handleException("Unable to get AxisEngine", fault, request, response);
129 return;
130 }
131
132
133 MessageContext messageContext = createMessageContext(axisEngine, request, response);
134
135
136 messageContext.setUsername(request.getRemoteUser());
137
138
139 String serviceName = request.getServletPath();
140
141 try {
142 service = axisEngine.getService(serviceName);
143 } catch (AxisFault fault) {
144 handleException("Unable to get SOAPService", fault, request, response);
145 return;
146 }
147
148
149 if (service == null) {
150 handleException("No SOAPService object returned", new NullPointerException("service is null"), request, response);
151 return;
152 }
153
154
155 try {
156 messageContext.setService(service);
157 } catch (AxisFault af) {
158 handleException("Unable to set SOAPService in messageContext", af, request, response);
159 return;
160 }
161
162
163 String queryString = request.getQueryString();
164
165
166
167
168
169 if (queryString != null && queryString.equalsIgnoreCase("wsdl")) {
170
171
172 Document wsdl = null;
173
174
175 try {
176 service.generateWSDL(messageContext);
177 } catch (AxisFault af) {
178 handleException("Unable to generate WSDL", af, request, response);
179 return;
180 }
181
182
183 Object object = messageContext.getProperty("WSDL");
184 if (object instanceof Document)
185 wsdl = (Document) object;
186
187
188 if (wsdl == null) {
189 handleException("No WSDL data available", new NullPointerException("wsdl is null"), request, response);
190 return;
191 }
192
193
194 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
195 XMLSerializer xmlSerializer = new XMLSerializer();
196 xmlSerializer.setOutputByteStream(outputStream);
197
198
199 try {
200 xmlSerializer.serialize(wsdl);
201 } catch (IOException ioe) {
202 handleException("Unable to serialize WSDL", ioe, request, response);
203 return;
204 }
205
206
207 response.setCharacterEncoding("UTF-8");
208 response.setContentType("text/xml; charset=UTF-8");
209 printWriter.print(outputStream.toString());
210
211 } else {
212
213 RequestDispatcher requestDispatcher = request.getSession().getServletContext().getNamedDispatcher("Axis.JSP");
214
215
216 request.setAttribute("serviceName", serviceName);
217
218
219 try {
220 requestDispatcher.forward(request, response);
221 } catch (Exception e) {
222
223
224 return;
225 }
226 }
227 }
228
229
230 /***
231 * Handles HTTP POST requests. This method does the real work, handling the
232 * SOAP requests.
233 * @param request
234 * The incoming HTTP request object.
235 * @param response
236 * The outgoing HTTP response object.
237 */
238 public void doPost(final HttpServletRequest request, final HttpServletResponse response) {
239
240
241 if (request == null) {
242 messageLogger.logCritical("Response object cannot be null", new NullPointerException("request is null"));
243 return;
244 }
245
246 if (response == null) {
247 messageLogger.logCritical("Response object cannot be null", new NullPointerException("response is null"));
248 return;
249 }
250
251
252 response.setBufferSize(8192);
253
254
255 AxisEngine axisEngine = null;
256
257
258 Message requestMessage = null;
259
260
261 SOAPService service = null;
262
263
264 try {
265 axisEngine = getEngine();
266 } catch (AxisFault fault) {
267 handleException("Unable to get AxisEngine", fault, request, response);
268 return;
269 }
270
271
272
273
274
275 MessageContext messageContext = createMessageContext(axisEngine, request, response);
276
277
278 messageContext.setUsername(request.getRemoteUser());
279
280
281 String serviceName = request.getServletPath();
282
283
284
285
286
287 try {
288 service = axisEngine.getService(serviceName);
289 } catch (AxisFault fault) {
290 handleException("Unable to get SOAPService", fault, request, response);
291 return;
292 }
293
294 if (service == null) {
295 handleException("No SOAPService object returned", new NullPointerException("service is null"), request, response);
296 return;
297 }
298
299
300 try {
301 messageContext.setService(service);
302 } catch (AxisFault af) {
303 handleException("Unable to set SOAPService in messageContext", af, request, response);
304 return;
305 }
306
307
308
309
310
311 try {
312 requestMessage = new Message(request.getInputStream(), false, request.getHeader("Content-Type"), request.getHeader("Content-Location"));
313 } catch (IOException ioe) {
314 handleException("Unable to get InputStream from request", ioe, request, response);
315 return;
316 }
317
318
319 messageContext.setRequestMessage(requestMessage);
320
321
322 String soapAction = request.getHeader("SOAPAction");
323
324
325
326
327
328 if (soapAction == null)
329 soapAction = request.getRequestURI();
330
331
332 messageContext.setUseSOAPAction(true);
333 messageContext.setSOAPActionURI(soapAction);
334
335
336 messageContext.setSession(new AxisHttpSession(request));
337
338
339
340
341
342 try {
343 axisEngine.invoke(messageContext);
344 } catch (AxisFault af) {
345
346 if ((af.getFaultString().startsWith("No such operation")) ||
347 (af.getFaultString().startsWith("org.xml.sax.SAXException"))) {
348
349
350 IllegalInputException e = new IllegalInputException(af.getFaultString());
351 handleException("Invocation of the Axis engine failed", e, request, response);
352
353 } else
354
355
356 handleException("Invocation of the axis engine failed", af, request, response);
357
358 return;
359 }
360
361
362 Message responseMessage = messageContext.getResponseMessage();
363
364
365 if (responseMessage == null) {
366 handleException("No response from engine", new NullPointerException("responseMessage is null"), request, response);
367 return;
368 }
369
370
371
372
373
374 try {
375 response.setContentType(responseMessage.getContentType(messageContext.getSOAPConstants()));
376 } catch (AxisFault af) {
377 handleException("Unable to retrieve content type of response", af, request, response);
378
379 response.setContentType("application/soap+xml");
380 }
381
382
383 try {
384 responseMessage.writeTo(response.getOutputStream());
385 } catch (Exception e) {
386 handleException("Unable to write response to client", e, request, response);
387 return;
388 }
389
390 }
391
392
393 /***
394 * Creates a new MessageContext, initialized with some standard values.
395 * @param axisEngine
396 * The AxisEngine that will be used to handle SOAP operations.
397 * @param request
398 * The incoming request.
399 * @param response
400 * The outgoing response.
401 * @return An initialized MessageContext.
402 */
403 private MessageContext createMessageContext(final AxisEngine axisEngine, final HttpServletRequest request, final HttpServletResponse response) {
404
405
406 MessageContext messageContext = new MessageContext(axisEngine);
407
408
409 messageContext.setTransportName("transport.name");
410
411
412 messageContext.setProperty(Constants.MC_RELATIVE_PATH, request.getServletPath());
413 messageContext.setProperty(Constants.MC_REMOTE_ADDR, request.getRemoteAddr());
414 messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);
415 messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, request);
416 messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, response);
417 messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, request.getPathInfo());
418 messageContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION, getWebInfPath());
419 messageContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION, request.getHeader(HTTPConstants.HEADER_AUTHORIZATION));
420
421
422 ServletEndpointContextImpl endpointContext = new ServletEndpointContextImpl();
423 messageContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, endpointContext);
424
425
426 String realPath = getServletContext().getRealPath(request.getServletPath());
427
428 if (realPath != null)
429 messageContext.setProperty(Constants.MC_REALPATH, realPath);
430
431
432 messageContext.setProperty(Constants.MC_CONFIGPATH, getWebInfPath());
433
434
435 messageContext.setProperty(MessageContext.TRANS_URL, request.getRequestURL().toString());
436
437 return messageContext;
438 }
439
440
441 /***
442 * Logs exception with message and prints user friendly error message to
443 * client.
444 * @param message
445 * Message to be logged with the exception.
446 * @param exception
447 * The exception to be handled.
448 * @param request
449 * Request object for this invocation.
450 * @param response
451 * Response object for this invocation.
452 */
453 private void handleException(final String message, final Exception exception, final HttpServletRequest request, final HttpServletResponse response) {
454
455
456 response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
457
458
459 Throwable cause = null;
460 if (exception instanceof AxisFault)
461 cause = exception.getCause();
462 else
463 cause = exception;
464
465
466 RequestDispatcher requestDispatcher;
467
468
469 if (request.getMethod().equals("POST") && request.getHeader("SOAPAction") != null) {
470
471
472
473
474
475 if (cause instanceof SOAPException) {
476
477
478 request.setAttribute("faultCode", ((SOAPException) cause).getFaultcode());
479 request.setAttribute("faultString", ((SOAPException) cause).getFaultstring());
480
481 } else if (cause instanceof RemoteException) {
482
483
484
485 request.setAttribute("faultCode", "Server");
486 request.setAttribute("faultString", cause.getMessage());
487
488 } else {
489
490
491 InternalException internal = new InternalException("");
492 request.setAttribute("faultCode", internal.getFaultcode());
493 request.setAttribute("faultString", internal.getFaultstring());
494 messageLogger.logCritical("Unknown internal exception", cause);
495
496 }
497
498
499 messageLogger.logWarn("Replying with SOAP Fault - faultCode: '" + request.getAttribute("faultCode") + "' faultString: '" + request.getAttribute("faultString") + "'", cause);
500
501
502 requestDispatcher = request.getSession().getServletContext().getNamedDispatcher("Axis-SOAP-Error.JSP");
503
504 } else {
505
506
507 request.setAttribute("logMessage", message);
508 requestDispatcher = request.getSession().getServletContext().getNamedDispatcher("Axis-Error.JSP");
509
510 }
511
512
513 try {
514 requestDispatcher.forward(request, response);
515 } catch (Exception e) {
516 messageLogger.logCritical("Unable to dispatch to Axis error jsp", e);
517 return;
518 }
519 }
520 }