soapservlet.java
来自「it is a tools for developing J2ME applic」· Java 代码 · 共 209 行
JAVA
209 行
/* Copyright (c) 2003,2004, Stefan Haustein, Oberhausen, Rhld., Germany
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE. */
package org.ksoap2.servlet;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
// import org.kobjects.serialization.*;
import org.ksoap2.*;
import org.ksoap2.serialization.*;
import org.kxml2.io.*;
import org.xmlpull.v1.*;
/**
* copy-paste seans interop server orb here as needed....
*
* some design issues: - path and soapaction are not considered. soapaction is
* deprecated; for multiple paths, please use multiple servlets.
*/
public class SoapServlet extends HttpServlet {
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER12);
/** static mapping paths -> objects */
Hashtable instanceMap = new Hashtable();
/**
* the default operation is to map request.getPathInfo to an instance using
* the information given by buildInstance. The returned instance is used as
* target object for the method invocation. Please overwrite this method in
* order to define your own (generic) mapping. If no mapping is found, the
* servlet itself is returned.
*/
protected Object getInstance(HttpServletRequest request) {
if (request.getPathInfo() == null)
return this;
Object result = instanceMap.get(request.getPathInfo());
return (result != null) ? result : this;
}
/** Publish all public methods of the given class */
public void publishClass(Class service, String namespace) {
Method[] methods = service.getMethods();
for (int i = 0; i < methods.length; i++) {
if (Modifier.isPublic(methods[i].getModifiers())) {
Class[] types = methods[i].getParameterTypes();
PropertyInfo[] info = new PropertyInfo[types.length];
for (int j = 0; j < types.length; j++) {
info[j] = new PropertyInfo();
info[j].type = types[j];
}
publishMethod(service, namespace, methods[i].getName(), info);
}
}
}
/**
* publish an instance by associating the instance with the given local
* path. Please note that (currently) also the methods need to be published
* separateley. Alternatively to this call, it is also possible to overwrite
* the getObject (HttpRequest request) method
*/
public void publishInstance(String path, Object instance) {
instanceMap.put(path, instance);
}
/**
* publish a method. Please note that also a corresponding instance needs to
* be published, either calling publishInstance or by overwriting
* getInstance (), except when the method is a method of the servlet itself.
*/
public void publishMethod(Class service, String namespace, String name, PropertyInfo[] parameters) {
SoapObject template = new SoapObject(namespace, name);
for (int i = 0; i < parameters.length; i++)
template.addProperty(parameters[i], null);
envelope.addTemplate(template);
}
/**
* convenience method; use this method if the paremeter types can be
* obtained via reflection
*/
public void publishMethod(Class service, String namespace, String name, String[] parameterNames) {
// find a fitting method
Method[] methods = service.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals(name) && methods[i].getParameterTypes().length == parameterNames.length) {
Class[] types = methods[i].getParameterTypes();
PropertyInfo[] info = new PropertyInfo[types.length];
for (int j = 0; j < types.length; j++) {
info[j] = new PropertyInfo();
info[j].name = parameterNames[j];
info[j].type = types[j];
}
publishMethod(service, namespace, name, info);
return;
}
}
throw new RuntimeException("Method not found!");
}
public SoapSerializationEnvelope getEnvelope() {
return envelope;
}
/**
* Please note: The classMap should not be set after publishing methods,
* because parameter type information may get lost!
*/
public void setEnvelope(SoapSerializationEnvelope envelope) {
this.envelope = envelope;
}
/**
* In order to filter requests, please overwrite doPost and call super for
* soap requests only
*/
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
try {
Object service = getInstance(req);
XmlPullParser parser = new KXmlParser();
parser.setInput(req.getInputStream(), req.getCharacterEncoding());
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
envelope.parse(parser);
SoapObject soapReq = (SoapObject) envelope.bodyIn;
SoapObject result = invoke(service, soapReq);
System.out.println("result: " + result);
envelope.bodyOut = result;
} catch (SoapFault f) {
f.printStackTrace();
envelope.bodyOut = f;
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} catch (Throwable t) {
t.printStackTrace();
SoapFault fault = new SoapFault();
fault.faultcode = "Server";
fault.faultstring = t.getMessage();
envelope.bodyOut = fault;
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
} finally {
res.setContentType("text/xml; charset=utf-8");
res.setHeader("Connection", "close");
StringWriter sw = new StringWriter();
XmlSerializer writer = new KXmlSerializer();
writer.setOutput(sw);
try {
envelope.write(writer);
} catch (Exception e) {
e.printStackTrace();
}
writer.flush();
System.out.println("result xml: " + sw);
Writer w = res.getWriter();
w.write(sw.toString());
w.close();
}
res.flushBuffer();
}
SoapObject invoke(Object service, SoapObject soapReq) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String name = soapReq.getName();
Class types[] = new Class[soapReq.getPropertyCount()];
Object[] args = new Object[soapReq.getPropertyCount()];
PropertyInfo arg = new PropertyInfo();
Hashtable properties = new Hashtable();
for (int i = 0; i < types.length; i++) {
soapReq.getPropertyInfo(i, properties, arg);
types[i] = (Class) arg.type;
args[i] = soapReq.getProperty(i);
}
// expensive invocation here.. optimize with method cache,
// want to support method overloading so need to figure in
// the arg types..
Method method = service.getClass().getMethod(name, types);
Object result = method.invoke(service, args);
System.out.println("result:" + result);
SoapObject response = new SoapObject(soapReq.getNamespace(), name + "Response");
if (result != null)
response.addProperty("return", result);
return response;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?