You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by st...@apache.org on 2002/09/07 02:09:03 UTC
cvs commit: xml-axis/java/src/org/apache/axis/transport/http AxisServlet.java
stevel 2002/09/06 17:09:03
Modified: java/src/org/apache/axis/transport/http AxisServlet.java
Log:
Here is the big change to axisservlet to fix many bugs. there is still one niggle out there to do with .jws files; I will deal with this over the weekend
-GET methods return XML
-GET methods work on .jws
-invalid-path?wsdl returns 404 not 500
-much cleaning up of structure of doGet(); teased many clauses out into their own methods
***dont panic, I havent gone near post***
Revision Changes Path
1.140 +296 -162 xml-axis/java/src/org/apache/axis/transport/http/AxisServlet.java
Index: AxisServlet.java
===================================================================
RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/transport/http/AxisServlet.java,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -r1.139 -r1.140
--- AxisServlet.java 23 Aug 2002 19:07:19 -0000 1.139
+++ AxisServlet.java 7 Sep 2002 00:09:03 -0000 1.140
@@ -62,6 +62,7 @@
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
+import java.net.HttpURLConnection;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
@@ -69,12 +70,14 @@
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpUtils;
import javax.xml.soap.SOAPException;
+import javax.xml.namespace.QName;
import org.apache.axis.AxisEngine;
import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
+import org.apache.axis.ConfigurationException;
import org.apache.axis.description.OperationDesc;
import org.apache.axis.description.ServiceDesc;
import org.apache.axis.handlers.soap.SOAPService;
@@ -140,6 +143,8 @@
protected String getJWSClassDir() { return jwsClassDir; }
+
+
/**
* create a new servlet instance
*/
@@ -184,18 +189,18 @@
* of various kinds, not real SOAP actions.
*
* @todo for secure installations, dont stack trace on faults
- * @param req
- * @param res
+ * @param request request in
+ * @param response request out
* @throws ServletException
* @throws IOException
*/
- public void doGet(HttpServletRequest req, HttpServletResponse res)
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
if (isDebug)
log.debug("Enter: doGet()");
- PrintWriter writer = res.getWriter();
+ PrintWriter writer = response.getWriter();
try
{
@@ -203,17 +208,26 @@
ServletContext servletContext =
getServletConfig().getServletContext();
- String pathInfo = req.getPathInfo();
- String realpath = servletContext.getRealPath(req.getServletPath());
+ String pathInfo = request.getPathInfo();
+ String realpath = servletContext.getRealPath(request.getServletPath());
if (realpath == null) {
- realpath = req.getServletPath();
+ realpath = request.getServletPath();
}
boolean wsdlRequested = false;
boolean listRequested = false;
+ boolean hasParameters = request.getParameterNames().hasMoreElements();
+
+ //JWS pages are special; they are the servlet path and there
+ //is no pathinfo...we map the pathinfo to the servlet path to keep
+ //it happy
+ boolean isJWSPage = request.getRequestURI().endsWith(".jws");
+ if(isJWSPage) {
+ pathInfo= request.getServletPath();
+ }
// check first if we are doing WSDL or a list operation
- String queryString = req.getQueryString();
+ String queryString = request.getQueryString();
if (queryString != null) {
if (queryString.equalsIgnoreCase("wsdl")) {
wsdlRequested = true;
@@ -222,41 +236,18 @@
}
}
- // If the user requested the servlet (i.e. /axis/services/)
- // with no service name, present the user with a list of deployed
- // services to be helpful
- // Don't do this if we are doing WSDL or list.
- if (!wsdlRequested && !listRequested &&
- (pathInfo == null || pathInfo.equals(""))) {
- res.setContentType("text/html");
- writer.println("<h2>And now... Some Services</h2>");
- Iterator i = engine.getConfig().getDeployedServices();
- writer.println("<ul>");
- while (i.hasNext()) {
- ServiceDesc sd = (ServiceDesc)i.next();
- StringBuffer sb = new StringBuffer();
- sb.append("<li>");
- sb.append(sd.getName());
- sb.append(" <a href=\"../services/");
- sb.append(sd.getName());
- sb.append("?wsdl\"><i>(wsdl)</i></a></li>");
- writer.println(sb.toString());
- ArrayList operations = sd.getOperations();
- if (!operations.isEmpty()) {
- writer.println("<ul>");
- for (Iterator it = operations.iterator(); it.hasNext();) {
- OperationDesc desc = (OperationDesc) it.next();
- writer.println("<li>" + desc.getName());
- }
- writer.println("</ul>");
- }
- }
- writer.println("</ul>");
+ boolean hasNoPath = (pathInfo == null || pathInfo.equals(""));
+ if (!wsdlRequested && !listRequested && hasNoPath) {
+ // If the user requested the servlet (i.e. /axis/servlet/AxisServlet)
+ // with no service name, present the user with a list of deployed
+ // services to be helpful
+ // Don't do this if we are doing WSDL or list.
+ reportAvailableServices(response, writer, request);
} else if (realpath != null) {
// We have a pathname, so now we perform WSDL or list operations
// get message context w/ various properties set
- MessageContext msgContext = createMessageContext(engine, req, res);
+ MessageContext msgContext = createMessageContext(engine, request, response);
try {
// NOTE: HttpUtils.getRequestURL has been deprecated.
@@ -268,120 +259,25 @@
// scenario rather than the actual host name.
//
// ? Still true? For which JVM's?
- String url = HttpUtils.getRequestURL(req).toString();
+ String url = HttpUtils.getRequestURL(request).toString();
msgContext.setProperty(MessageContext.TRANS_URL, url);
+
if (wsdlRequested) {
// Do WSDL generation
- engine.generateWSDL(msgContext);
- Document doc = (Document) msgContext.getProperty("WSDL");
- if (doc != null) {
- res.setContentType("text/xml");
- XMLUtils.DocumentToWriter(doc, writer);
- } else {
- //BUGBUG: this never gets called
- res.setStatus(java.net.HttpURLConnection.HTTP_NOT_FOUND);
- res.setContentType("text/html");
- writer.println("<h2>" +
- JavaUtils.getMessage("error00") +
- "</h2>");
- writer.println("<p>" +
- JavaUtils.getMessage("noWSDL00") +
- "</p>");
- }
+ processWsdlRequest(msgContext, response, writer);
} else if (listRequested) {
// Do list, if it is enabled
- if (enableList) {
- Document doc = Admin.listConfig(engine);
- if (doc != null) {
- res.setContentType("text/xml");
- XMLUtils.DocumentToWriter(doc, writer);
- } else {
- //TODO: error code
- res.setContentType("text/html");
- writer.println("<h2>" +
- JavaUtils.getMessage("error00") +
- "</h2>");
- writer.println("<p>" +
- JavaUtils.getMessage("noDeploy00") +
- "</p>");
- }
- } else {
- // list not enable, return error
- //TODO: error code
- res.setContentType("text/html");
- writer.println("<h2>" +
- JavaUtils.getMessage("error00") +
- "</h2>");
- writer.println("<p><i>?list</i>" +
- JavaUtils.getMessage("disabled00") +
- "</p>");
- }
- } else if (req.getParameterNames().hasMoreElements()) {
+ processListRequest(response, writer);
+ } else if (hasParameters) {
// If we have ?method=x¶m=y in the URL, make a stab
// at invoking the method with the parameters specified
// in the URL
- res.setContentType("text/html");
- Enumeration enum = req.getParameterNames();
- String method = null;
- String args = "";
- while (enum.hasMoreElements()) {
- String param = (String) enum.nextElement();
- if (param.equalsIgnoreCase("method")) {
- method = req.getParameter(param);
- } else {
- args += "<" + param + ">" +
- req.getParameter(param) +
- "</" + param + ">";
- }
- }
-
- if (method == null) {
- writer.println("<h2>" +
- JavaUtils.getMessage("error00") +
- ": " +
- JavaUtils.getMessage("invokeGet00") +
- "</h2>");
- writer.println("<p>" +
- JavaUtils.getMessage("noMethod01") +
- "</p>");
- } else {
- String body =
- "<" + method + ">" + args + "</" + method + ">";
+ processMethodRequest(msgContext, request, response, writer);
- String msgtxt =
- "<SOAP-ENV:Envelope" +
- " xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
- "<SOAP-ENV:Body>" + body + "</SOAP-ENV:Body>" +
- "</SOAP-ENV:Envelope>";
-
- ByteArrayInputStream istream =
- new ByteArrayInputStream(msgtxt.getBytes());
-
- Message msg = new Message(istream, false);
- msgContext.setRequestMessage(msg);
-
-// if (msg != null) {
-// writer.println(msg.getAsString());
-// return;
-// }
- engine.invoke(msgContext);
- Message respMsg = msgContext.getResponseMessage();
- if (respMsg != null) {
- writer.println("<p>" +
- JavaUtils.getMessage("gotResponse00") +
- "</p>");
- writer.println(respMsg.getSOAPPartAsString());
- } else {
- writer.println("<p>" +
- JavaUtils.getMessage("noResponse01") +
- "</p>");
- }
- }
} else {
- res.setContentType("text/html");
// See if we can locate the desired service. If we
// can't, return a 404 Not Found. Otherwise, just
@@ -396,32 +292,23 @@
SOAPService s = engine.getService(serviceName);
if (s == null) {
- // Outta here, no such service....
- res.setStatus(java.net.HttpURLConnection.HTTP_NOT_FOUND);
- res.setContentType("text/html");
+ // no such service....
+ response.setStatus(java.net.HttpURLConnection.HTTP_NOT_FOUND);
+ response.setContentType("text/html");
writer.println("<h2>" +
JavaUtils.getMessage("error00") + "</h2>");
writer.println("<p>" +
JavaUtils.getMessage("noService06") +
"</p>");
- return;
+ } else {
+ //print a snippet of service info.
+ reportServiceInfo(response, writer, s, serviceName);
}
-
- //print a snippet of service info.
- writer.println("<h1>" + serviceName +
- "</h1>");
- writer.println(
- "<p>" +
- JavaUtils.getMessage("axisService00") +
- "</p>");
- writer.println(
- "<i>" +
- JavaUtils.getMessage("perhaps00") +
- "</i>");
}
} catch (AxisFault fault) {
- res.setContentType("text/html");
- res.setStatus(500);
+ log.error(JavaUtils.getMessage("exception00"), fault);
+ response.setContentType("text/html");
+ response.setStatus(500);
writer.println("<h2>" +
JavaUtils.getMessage("error00") + "</h2>");
writer.println("<p>" +
@@ -430,8 +317,9 @@
writer.println("<pre>Fault - " + fault.toString() + " </pre>");
writer.println("<pre>" + fault.dumpToString() + " </pre>");
} catch (Exception e) {
- res.setContentType("text/html");
- res.setStatus(500);
+ log.error(JavaUtils.getMessage("exception00"), e);
+ response.setContentType("text/html");
+ response.setStatus(500);
writer.println("<h2>" +
JavaUtils.getMessage("error00") +
"</h2>");
@@ -439,7 +327,10 @@
JavaUtils.getMessage("somethingWrong00") +
"</p>");
writer.println("<pre>Exception - " + e + "<br>");
- writer.println(JavaUtils.stackToString(e));
+ //dev systems only give fault dumps
+ if (isDevelopment()) {
+ writer.println(JavaUtils.stackToString(e));
+ }
writer.println("</pre>");
}
}
@@ -449,7 +340,7 @@
// print a message informing the user that they reached
// the servlet.
- res.setContentType("text/html");
+ response.setContentType("text/html");
writer.println( "<html><h1>Axis HTTP Servlet</h1>" );
writer.println( JavaUtils.getMessage("reachedServlet00"));
@@ -467,6 +358,246 @@
}
/**
+ * scan through the request for parameters, invoking the endpoint
+ * if we get a method param.
+ * @param msgContext current message
+ * @param request incoming requests
+ * @param response response to generate
+ * @param writer output stream
+ * @throws AxisFault if anything goes wrong during method execution
+ */
+ protected void processMethodRequest(MessageContext msgContext,
+ HttpServletRequest request,
+ HttpServletResponse response,
+ PrintWriter writer) throws AxisFault {
+ Enumeration enum = request.getParameterNames();
+ String method = null;
+ String args = "";
+ while (enum.hasMoreElements()) {
+ String param = (String) enum.nextElement();
+ if (param.equalsIgnoreCase("method")) {
+ method = request.getParameter(param);
+ } else {
+ args += "<" + param + ">" +
+ request.getParameter(param) +
+ "</" + param + ">";
+ }
+ }
+
+ if (method == null) {
+ response.setContentType("text/html");
+ //TODO: what error code should we send back for no method?
+ writer.println("<h2>" +
+ JavaUtils.getMessage("error00") +
+ ": " +
+ JavaUtils.getMessage("invokeGet00") +
+ "</h2>");
+ writer.println("<p>" +
+ JavaUtils.getMessage("noMethod01") +
+ "</p>");
+ } else {
+ invokeEndpointFromGet(msgContext, response, writer, method, args);
+
+ }
+ }
+
+ /**
+ * handle a ?wsdl request
+ * @param msgContext message context so far
+ * @param response response to write to
+ * @param writer output stream
+ * @throws AxisFault when anything other than a Server.NoService fault is reported
+ * during WSDL generation
+ */
+ protected void processWsdlRequest(MessageContext msgContext,
+ HttpServletResponse response,
+ PrintWriter writer) throws AxisFault {
+ AxisEngine engine = getEngine();
+ try {
+ engine.generateWSDL(msgContext);
+ Document doc = (Document) msgContext.getProperty("WSDL");
+ if (doc != null) {
+ response.setContentType("text/xml");
+ XMLUtils.DocumentToWriter(doc, writer);
+ } else {
+ reportNoWSDL(response, writer);
+ }
+ } catch (AxisFault axisFault) {
+ //the no-service fault is mapped to a no-wsdl error
+ if(axisFault.getFaultCode() .equals(Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
+ reportNoWSDL(response, writer);
+ } else {
+ throw axisFault;
+ }
+ }
+ }
+
+ /**
+ * invoke an endpoint from a get request by building an XML request and
+ * handing it down
+ * @param msgContext current message
+ * @param response to return data
+ * @param writer output stream
+ * @param method method to invoke (may be null)
+ * @param args argument list in XML form
+ * @throws AxisFault
+ */
+ protected void invokeEndpointFromGet(MessageContext msgContext,
+ HttpServletResponse response,
+ PrintWriter writer,
+ String method,
+ String args) throws AxisFault {
+ AxisEngine engine = getEngine();
+ String body =
+ "<" + method + ">" + args + "</" + method + ">";
+
+ String msgtxt =
+ "<SOAP-ENV:Envelope" +
+ " xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
+ "<SOAP-ENV:Body>" + body + "</SOAP-ENV:Body>" +
+ "</SOAP-ENV:Envelope>";
+
+ ByteArrayInputStream istream =
+ new ByteArrayInputStream(msgtxt.getBytes());
+
+ Message msg = new Message(istream, false);
+ msgContext.setRequestMessage(msg);
+ engine.invoke(msgContext);
+ Message respMsg = msgContext.getResponseMessage();
+ if (respMsg != null) {
+ response.setContentType("text/xml");
+ writer.println(respMsg.getSOAPPartAsString());
+ } else {
+ //TODO: error code
+ writer.println("<p>" +
+ JavaUtils.getMessage("noResponse01") +
+ "</p>");
+ }
+ }
+
+ /**
+ * print a snippet of service info.
+ * @param service service
+ * @param writer output channel
+ * @param serviceName where to put stuff
+ */
+
+ protected void reportServiceInfo(HttpServletResponse response, PrintWriter writer, SOAPService service, String serviceName) {
+ response.setContentType("text/html");
+
+ writer.println("<h1>"
+ + service.getName()
+ +"</h1>");
+ writer.println(
+ "<p>" +
+ JavaUtils.getMessage("axisService00") +
+ "</p>");
+ writer.println(
+ "<i>" +
+ JavaUtils.getMessage("perhaps00") +
+ "</i>");
+ }
+
+ /**
+ * respond to the ?list command.
+ * if enableList is set, we list the engine config. If it isnt, then an
+ * error is written out
+ * @param response
+ * @param writer
+ * @throws AxisFault
+ */
+ protected void processListRequest(HttpServletResponse response, PrintWriter writer) throws AxisFault {
+ AxisEngine engine = getEngine();
+ if (enableList) {
+ Document doc = Admin.listConfig(engine);
+ if (doc != null) {
+ response.setContentType("text/xml");
+ XMLUtils.DocumentToWriter(doc, writer);
+ } else {
+ //error code is 404
+ response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
+ response.setContentType("text/html");
+ writer.println("<h2>" +
+ JavaUtils.getMessage("error00") +
+ "</h2>");
+ writer.println("<p>" +
+ JavaUtils.getMessage("noDeploy00") +
+ "</p>");
+ }
+ } else {
+ // list not enable, return error
+ //error code is, what, 401
+ response.setStatus(HttpURLConnection.HTTP_FORBIDDEN);
+ response.setContentType("text/html");
+ writer.println("<h2>" +
+ JavaUtils.getMessage("error00") +
+ "</h2>");
+ writer.println("<p><i>?list</i>" +
+ JavaUtils.getMessage("disabled00") +
+ "</p>");
+ }
+ }
+
+ /**
+ * report that we have no WSDL
+ * @param res
+ * @param writer
+ */
+ protected void reportNoWSDL(HttpServletResponse res, PrintWriter writer) {
+ res.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
+ res.setContentType("text/html");
+ writer.println("<h2>" +
+ JavaUtils.getMessage("error00") +
+ "</h2>");
+ writer.println("<p>" +
+ JavaUtils.getMessage("noWSDL00") +
+ "</p>");
+ }
+
+ /**
+ * This method lists the available services; it is called when there is
+ * nothing to execute on a GET
+ * @param response
+ * @param writer
+ * @param request
+ * @throws ConfigurationException
+ * @throws AxisFault
+ */
+ protected void reportAvailableServices(HttpServletResponse response,
+ PrintWriter writer,
+ HttpServletRequest request)
+ throws ConfigurationException, AxisFault {
+ AxisEngine engine = getEngine();
+ response.setContentType("text/html");
+ writer.println("<h2>And now... Some Services</h2>");
+ Iterator i = engine.getConfig().getDeployedServices();
+ String baseURL = getWebappBase(request)+"/services/";
+ writer.println("<ul>");
+ while (i.hasNext()) {
+ ServiceDesc sd = (ServiceDesc)i.next();
+ StringBuffer sb = new StringBuffer();
+ sb.append("<li>");
+ String name = sd.getName();
+ sb.append(name);
+ sb.append(" <a href=\"");
+ sb.append(baseURL);
+ sb.append(name);
+ sb.append("?wsdl\"><i>(wsdl)</i></a></li>");
+ writer.println(sb.toString());
+ ArrayList operations = sd.getOperations();
+ if (!operations.isEmpty()) {
+ writer.println("<ul>");
+ for (Iterator it = operations.iterator(); it.hasNext();) {
+ OperationDesc desc = (OperationDesc) it.next();
+ writer.println("<li>" + desc.getName());
+ }
+ writer.println("</ul>");
+ }
+ }
+ writer.println("</ul>");
+ }
+
+ /**
* Process a POST to the servlet by handing it off to the Axis Engine.
* Here is where SOAP messages are received
* @param req posted request
@@ -686,6 +817,7 @@
* Message processing routine convert it - we don't do it since we
* don't know how it's going to be used - perhaps it might not
* even need to be parsed.
+ * @return a message context
*/
private MessageContext createMessageContext(AxisEngine engine,
HttpServletRequest req,
@@ -795,6 +927,7 @@
/**
* Provided to allow overload of default JWSClassDir
* by derived class.
+ * @return directory for JWS files
*/
protected String getDefaultJWSClassDir() {
return getWebInfPath() + File.separator + "jwsClasses";
@@ -803,6 +936,7 @@
/**
* Return the HTTP protocol level 1.1 or 1.0
* by derived class.
+ * @return one of the HTTPConstants values
*/
protected String getProtocolVersion(HttpServletRequest req){
String ret= HTTPConstants.HEADER_PROTOCOL_V10;