Edited at

Wicket で XML-RPC API を作る

More than 1 year has passed since last update.


環境


  • Wicket 7.10

  • Tomcat 8

  • Java 8

  • org.apache.xmlrpc 3.1.3


背景

Wicket で XML-RPCがやりたい!


XML-RPC受信用のページを準備


  • respond, detach を override


XmlRpcPage.java

public class XmlRpcPage extends WebPage {

private static final long serialVersionUID = 1L;

public XmlRpcPage(PageParameters params) {
super(params);
setStatelessHint(true);
Session.get().bind();

HttpServletRequest request = (HttpServletRequest)getRequestCycle().getRequest().getContainerRequest();
HttpServletResponse response = (HttpServletResponse)getRequestCycle().getResponse().getContainerResponse();

getRequestCycle().replaceAllRequestHandlers(new IRequestHandler() {

@Override
public void respond(IRequestCycle requestCycle) {
try {
processXmlRpcRequest(request, response);
} catch (ServletException | IOException e) {
throw new WicketRuntimeException(e);
}
}

@Override
public void detach(IRequestCycle requestCycle) {

}

});
}

/**
* Get XML-RPC server
* @return
*/

protected XmlRpcServletServer getXmlRpcServer() {
return ((WicketApplication)getApplication()).getXmlRpcServer();
}

/**
* Process XML-RPC request
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/

protected void processXmlRpcRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
getXmlRpcServer().execute(request, response);
}

@Override
public Markup getAssociatedMarkup() {
return null;
}

@Override
protected void configureResponse(WebResponse response) {
final String encoding = getApplication().getRequestCycleSettings().getResponseRequestEncoding();
response.setContentType("application/xhtml+xml; charset=" + encoding);
}
}



Wicketアプリケーションの設定


  • XmlRpc用 Server, Config 準備



WicketApplication.java


protected XmlRpcServletServer xmlRpcServer = null;
protected XmlRpcServerConfigImpl xmlRpcConfig = null;

// コンストラクタ
public WicketApplication() {
super();
xmlRpcServer = new XmlRpcServletServer();
xmlRpcConfig = new XmlRpcServerConfigImpl();
}



  • 初期化処理メソッド


WicketApplication.java

    /*

* Initialize xmlrpc server
*/

public void initXmlRpc() {

/* configure xml-rpc server */
xmlRpcServer.setTypeFactory(new CustomTypeFactory(xmlRpcServer));

//CustomTypeConverterFactory は Xml-Rpcで型変換用のファクトリ
xmlRpcServer.setTypeConverterFactory(new CustomTypeConverterFactory());

xmlRpcConfig = (XmlRpcServerConfigImpl)this.xmlRpcServer.getConfig();
xmlRpcConfig.setBasicEncoding(XmlRpcConfigImpl.UTF8_ENCODING);
xmlRpcConfig.setEnabledForExceptions(true);
xmlRpcConfig.setEnabledForExtensions(true);

PropertyHandlerMapping mapping = createXmlRpcHandlerMapping();
this.xmlRpcServer.setHandlerMapping(mapping);
}


CustomTypeFactory は org.apache.xmlrpc.common.TypeFactoryImpl を extends したもの

CustomTypeConverterFactory は org.apache.xmlrpc.common.TypeConverterFactoryImpl を extends したもの


  • Xml-Rpcのマッピングメソッド


WicketApplication.java

    /**

* XML-RPC 用プロパティハンドラマップ生成
* @return
*/

private PropertyHandlerMapping createXmlRpcHandlerMapping() {

PropertyHandlerMapping mapping = new PropertyHandlerMapping();
mapping.setRequestProcessorFactoryFactory(new StatelessProcessorFactoryFactory());
mapping.setTypeConverterFactory(new CustomTypeConverterFactory());
try {
mapping.load(getClass().getClassLoader(), "xmlrpc.properties");
} catch (XmlRpcException | IOException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
logger.error("ERROR:\n"+sw.toString());
throw new WicketRuntimeException(e);
}
return mapping;
}



xmlrpc.properties

SampleService=my.api.xmlrpc.service.impl.SampleServiceImpl



  • initメソッド内で呼び出す


WicketApplication.java

        // initialize XML-RPC

initXmlRpc();


  • initメソッド内上記初期化後にページマウント


WicketApplication.java

        // xml-rpc base

mount(new MountedMapper("/XmlRpc", XmlRpcPage.class));


呼び出す


TestSampleXmlRpc.java

    public static void main(String[] args) throws Exception {

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://localhost:8080/sample/XmlRpc"));
config.setEnabledForExtensions(true);
config.setEnabledForExceptions(true);

XmlRpcClient client = new XmlRpcClient();
client.setTransportFactory(new XmlRpcLoggingTransportFactory(client));
client.setTypeFactory(new CustomTypeFactory(client));
client.setConfig(config);

Vector<Object> arg = new Vector<Object>();
arg.add("some.parameter");

Object response = client.execute("SampleService.sampleMethod", arg);
System.out.println("Response: " + response);
}


CustomTypeFactory は org.apache.xmlrpc.common.TypeFactoryImpl を extends したもの


その他

ご質問等あればお気軽にどうぞ。

エラーハンドリングはtry ~ catch で全てキャッチして結果を戻り値として返すようにしています。

(後で書こうかとも思いましたが、わざわざ書くほどの事でもなかった、、、)