配置
使用CXF可以非常方便的把普通的Java类发布为WebService。
首先在官网下载apache-cxf-3.1.1.zip
,解压后把lib
文件夹下的所有jar文件拷贝到项目中WebRoot/WEB-INF/lib
目录下
然后配置web.xml
,加入如下内容
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:services.xml
</param-value>
</context-param>
contextConfigLocation
的值指定了我们将要配置WebService的文件,而classpath信息记录在项目根目录下.classpath
文件中
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
/services/*
指定了访问WebService的路径
发布服务
然后编写服务的接口和实现类:
IRemoteIDEService.java
package com.jdeServer.service;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface IRemoteIDEService {
//如果不用@WebParam指定参数名,则参数名会变成arg0
public String getCompileResult(@WebParam(name="sourceFileContent") String sourceFileContent);
}
RemoteIDEServiceImpl.java
package com.jdeServer.service;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import Wgcc.dyGcc;
public class RemoteIDEServiceImpl implements IRemoteIDEService {
@Override
public String getCompileResult(String sourceFileContent) {
String uploadDir = "";
String WebRoot="";
String output="";
try {
Context context = new InitialContext();
WebRoot=(String) context.lookup("WebRoot");
uploadDir = (String) context.lookup("uploadDir");
output=(String) context.lookup("output");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//创建源文件
File file = new File(WebRoot+uploadDir, "sourceFile.c");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
}
//将代码写入源文件
try {
OutputStream out = new FileOutputStream(file, false);
out.write(sourceFileContent.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//编译源文件
String compileResult="";
dyGcc gcc=new dyGcc();
String errorFile=WebRoot+output+"\\error.txt";
try {
compileResult=gcc.compile(file.getAbsolutePath().toString(), errorFile);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return compileResult;
}
}
然后我们配置services.xml
,其内容如下
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<!-- 本来按照官网文档导入多个resource,但是会报错,删除其余report后正常 -->
<jaxws:endpoint id="remoteide"
implementor="com.jdeServer.service.RemoteIDEServiceImpl"
address="/RemoteIDEService"/>
</beans>
在这里我们发布了一个服务,implementor
指定了其实现类
启动服务器后访问http://[server ip address]:8080/[app name]/services/RemoteIDEService?wsdl
看到如下内容即表示WebService发布成功:
<xs:complexType name="getCompileResult">
<xs:sequence>
<xs:element minOccurs="0" name="sourceFileContent" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getCompileResultResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<wsdl:operation name="getCompileResult">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="getCompileResult">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getCompileResultResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
访问服务
上面的xml描述了这个WebService中的一个WebMethod,即getCompileResult
然后我们可以在客户端使用SOAP访问这个WebMethod:
RemoteCompileService.java
package com.jde.service;
import android.content.Context;
import com.jde.R;
import utils.ContextUtil;
import java.io.IOException;
//使用下面这几个包的时候要导入ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
/**
* Created by chansonzhang on 2015/7/17.
*/
public class RemoteCompileService {
static Context c= ContextUtil.getInstance();
private static final String SERVER= c.getString(R.string.server);
private static final String NAME_SPACE = "http://service.jdeServer.com/"; //对应服务器端的包名
private static final String WDSL_LINK = SERVER+"services/RemoteIDEService";
private String compileResult="";
public String getCompileResult() {
return compileResult;
}
public void setCompileResult(String compileResult) {
this.compileResult = compileResult;
}
public String getCompileResult(String sourceContent)
{
final String METHOD_NAME="getCompileResult";
final String SOAP_ACTION="";
/*此处的值可在wsdl中查到
如果写错会报出The given SOAPAction xxxx does not match an operation.*/
final String sContent=sourceContent;
//如果此处不使用线程,则会抛出android.os.NetworkOnMainThreadException,这是Android为了防止网络阻塞导致界面假死的举措
Thread thread=new Thread(){
public void run()
{
try {
SoapObject request=new SoapObject(NAME_SPACE,METHOD_NAME);
request.addProperty("sourceFileContent", sContent);//添加服务器端WebMethod所需的参数
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.bodyOut = request;
envelope.dotNet = false;
envelope.setOutputSoapObject(request);
HttpTransportSE ht = new HttpTransportSE(WDSL_LINK);
ht.call(SOAP_ACTION, envelope);
String ret = String.valueOf(envelope.getResponse());
setCompileResult(ret);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
};
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return compileResult;
}
}
附录:用到的值
服务器端
web.xml
<env-entry>
<env-entry-name>uploadDir</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>uploadedFiles</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>WebRoot</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value> E:\Document\workspace\MyEclipse 2015 CI\PCServer\WebRoot\</env-entry-value>
</env-entry>
<env-entry>
<env-entry-name>output</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>output</env-entry-value>
</env-entry>
客户端
strings.xml
<string name="server">http://202.117.**.***:8080/PCServer/</string>