WebService历来都很受重视,特别是Java阵营,WebService框架和技术层出不穷。知名的XFile(新的如CXF)、Axis1、Axis2等。

  而Sun公司也不甘落后,从早期的JAX-RPC到现在成熟的、支持RPC调用与消息传递的JAX-WS都经过了市场的考验,十分成熟,而且使用JAX-WS开发WebService的收益是很大的,它是轻量级的。 

一、WebService的开发方法

使用Java开发WebService时可以使用以下两种开发手段

    1、 使用JDK开发(1.6及以上版本)

    2、使用第三方组件,如CXF框架开发

二、使用JDK开发WebService

JAX-WS 2.0 有两种开发过程:自顶向下和自底向上。自顶向下方式指通过一个 WSDL 文件来创建Web Service,自底向上是从 Java 类出发创建 Web Service。两种开发过程最终形成的文件包括:

1.SEI(Service Endpoint Interface 发布的服务接口)。一个SEI对应WSDL中WebService的一个port,在Java中是一个Java接口。

2.SEI实现类。

3.WSDL和XSD文件。

 

我们使用JAX-WS开发WebService只需要很简单的几个步骤:写接口和实现=>发布=>生成客户端(测试或使用)。

2.1、开发WebService服务器端

  而在开发阶段我们也不需要导入外部jar包,因为这些api都是现成的。首先是接口的编写(接口中只需要把类注明为@WebService,把要暴露给客户端的方法注明为@WebMethod即可,其余如@WebResult、@WebParam等都不是必要的,而客户端和服务端的通信用RPC和Message-Oriented两种,区别和配置以后再说):

注解说明:

@WebService 注释在了Class之上,这告诉了JAXWS,此类为Webservice。@WebService注解让系统知道我们希望使用哪个接口来创建WSDL,本例中就是

HelloWService接口。


@WebMethod 注释在了public方法上,这告诉了JAXWS,此方法为soap方法。

接口:



package com.server.ws;

import java.util.Date;

import javax.jws.WebService;

import com.server.domain.PersonModel;

/**
* WebService接口
*/
@WebService(name = "HelloWS", targetNamespace = "http://www.client.com/ws/hello")
public interface HelloWService {
/**
* 返回字符串
*
* @return
*/
String index();

/**
* 两个整数相加
*
* @param x
* @param y
* @return 相加后的值
*/
Integer add(Integer x, Integer y);

/**
* 返回当前时间
*
* @return
*/
Date now();

/**
* 获取复杂类型
*
* @param name
* 用户姓名
* @param age
* 用户年龄
* @return 返回用户类
*/
PersonModel getPerson(String name, Integer age);
}


 

实现类(注解@WebService及其endpointInterface属性是必要的):



package com.server.ws.impl;

import java.util.Date;

import javax.jws.HandlerChain;
import javax.jws.WebService;

import com.server.domain.PersonModel;
import com.server.ws.HelloWService;

@WebService(
endpointInterface = "com.server.ws.HelloWService",
portName = "HelloWSPort",
serviceName = "HelloWSService",
targetNamespace = "http://www.client.com/ws/hello"
)
@HandlerChain(file="handler-chain.xml")
public class HelloWServiceImpl implements HelloWService {
public String index() {
return "hello";
}

public Integer add(Integer x, Integer y) {
return x + y;
}

public Date now() {
return new Date();
}

public PersonModel getPerson(String name, Integer age) {
PersonModel person = new PersonModel();
person.setAge(age);
person.setName(name);

return person;
}

}


实体对象:



package com.server.domain;

import java.io.Serializable;

public class PersonModel implements Serializable {
private static final long serialVersionUID = -7211227324542440039L;

private String name;
private Integer age;

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}

}


handler:



package com.server.ws.handler;

import java.io.IOException;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
* 记录SOAP请求及响应
*
*/
public class LoggerSOAPHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public void close(MessageContext context) {
}

@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}

@Override
public boolean handleMessage(SOAPMessageContext context) {
// 判断消息是输入还是输出
Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println(output ? "响应SOAP:" : "请求SOAP:");

SOAPMessage message = context.getMessage();

try {
message.writeTo(System.out);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

System.out.println("");
System.out.println("");

return true;
}

@Override
public Set<QName> getHeaders() {
return null;
}

}



package com.server.ws.handler;

import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
* 服务端请求校验Handler
*
*/
public class ValidateAuthHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public void close(MessageContext context) {
}

@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}

@Override
public boolean handleMessage(SOAPMessageContext context) {
// 判断消息是请求还是响应
Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

boolean result = false;

SOAPMessage message = context.getMessage();

//如果是请求,则执行校验
if(!output){
result = validate(message);

if(!result){
validateFail(message);
}
}

System.out.println(output ? "服务端响应:" : "服务端接收:");
try {
message.writeTo(System.out);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("\r\n");

return result;
}

/**
* 授权校验失败,在SOAPBody中添加SOAPFault
* @param message
*/
private void validateFail(SOAPMessage message) {
try {
SOAPEnvelope envelop = message.getSOAPPart().getEnvelope();

envelop.getHeader().detachNode();
envelop.addHeader();

envelop.getBody().detachNode();
SOAPBody body = envelop.addBody();

SOAPFault fault = body.getFault();

if (fault == null) {
fault = body.addFault();
}

fault.setFaultString("授权校验失败!");

message.saveChanges();
} catch (SOAPException e) {
e.printStackTrace();
}
}

/**
* 授权校验
* @param message
* @return 校验成功返回true,校验失败返回false
*/
private boolean validate(SOAPMessage message){
boolean result = false;

try {
SOAPEnvelope envelop = message.getSOAPPart().getEnvelope();
SOAPHeader header = envelop.getHeader();

if(header != null){
Iterator iterator = header.getChildElements(new QName("http://www.client.com/auth", "auth"));
SOAPElement auth = null;

if(iterator.hasNext()){
//获取auth
auth = (SOAPElement)iterator.next();

//获取name
Iterator it = auth.getChildElements(new QName("http://www.client.com/auth", "name"));
SOAPElement name = null;
if(it.hasNext()){
name = (SOAPElement)it.next();
}

//获取password
it = auth.getChildElements(new QName("http://www.client.com/auth", "password"));
SOAPElement password = null;
if(it.hasNext()){
password = (SOAPElement)it.next();
}

//判断name和password是否符合要求
if(name != null && password != null && "admin".equals(name.getValue()) && "admin".equals(password.getValue())){
result = true;
}
}
}

} catch (SOAPException e) {
e.printStackTrace();
}

return result;
}

@Override
public Set<QName> getHeaders() {
return null;
}

}


2.2、发布

发布一般有两种方式:

方式一:Endpoint.publish

A、通过运行WebServicePublish类,就可以将编写好的WebService发布



package com.server.publish;

import javax.xml.ws.Endpoint;

import com.server.ws.impl.HelloWServiceImpl;

/**
* 发布Web Service
*
*/
public class WebServicePublish {

public static void main(String[] args) {
// 定义WebService的发布地址,这个地址就是提供给外界访问Webervice的URL地址,URL地址格式为:http://ip:端口号/xxxx
// String address = "http://192.168.1.100:8989/";这个WebService发布地址的写法是合法的
// String address =
// "http://192.168.1.100:8989/Webservice";这个WebService发布地址的是合法的
String address = "http://localhost:8989/WS_Server/Webservice";
// 使用Endpoint类提供的publish方法发布WebService,发布时要保证使用的端口号没有被其他应用程序占用
Endpoint.publish(address, new HelloWServiceImpl());
System.out.println("发布webservice成功!");
}

}


访问上面配置的地址http://localhost:8989/WS_Server/Webservice结果如下:

JAX-WS(JWS)发布WebService_java

我的java工程结构是:

JAX-WS(JWS)发布WebService_xml_02

B、如果是Web项目,那么我们可以使用监听器或者Servlet来发布WebService,如下:

B.1、使用ServletContextListener监听器发布WebService



package com.server.publish;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.xml.ws.Endpoint;

import com.server.ws.impl.HelloWServiceImpl;

public class WebServicePublishListener implements ServletContextListener {

@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub

}

@Override
public void contextInitialized(ServletContextEvent arg0) {
// 定义WebService的发布地址,这个地址就是提供给外界访问Webervice的URL地址,URL地址格式为:http://ip:端口号/xxxx
// String address = "http://192.168.1.100:8989/";这个WebService发布地址的写法是合法的
// String address =
// "http://192.168.1.100:8989/Webservice";这个WebService发布地址的是合法的
String address = "http://localhost:8081/WS_Server/Webservice";
// 使用Endpoint类提供的publish方法发布WebService,发布时要保证使用的端口号没有被其他应用程序占用
Endpoint.publish(address, new HelloWServiceImpl());
System.out.println("发布webservice成功!");

}

}


xml配置如下:



<listener>
<listener-class>com.server.publish.WebServicePublishListener</listener-class>
</listener>


打包成war,部署到tomcat,并启动tomcat,访问及结果如下:

JAX-WS(JWS)发布WebService_J2EE_03

B.2、使用Servlet监听器发布WebService



package com.server.publish;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.xml.ws.Endpoint;

import com.server.ws.impl.HelloWServiceImpl;

/**
* 用于发布WebService的Servlet,使用Servlet3.0提供的@WebServlet注解将继承HttpServlet类的普通Java类标注为一个Servlet,
* 将value属性设置为空字符串,这样WebServicePublishServlet就不提供对外访问的路径
* loadOnStartup属性设置WebServicePublishServlet的初始化时机
*
*/
//@WebServlet(value="",loadOnStartup=0)
public class WebServicePublishServlet extends HttpServlet {
public void init() throws ServletException {
//WebService的发布地址
String address = "http://localhost:8888/WebService";
//发布WebService,HelloWServiceImpl类是WebServie接口的具体实现类
Endpoint.publish(address , new HelloWServiceImpl());
System.out.println("使用WebServicePublishServlet发布webservice成功!");
}
}


xml配置:



<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.server.publish.WebServicePublishServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/start</url-pattern>
</servlet-mapping>


打包成war,部署到tomcat,并启动tomcat,访问及结果如下:

JAX-WS(JWS)发布WebService_webservice_04

C、通过WebService配置文件sun-jaxws.xml

C.1、在WEB-INF中创建WebService配置文件sun-jaxws.xml,配置文件中一个WebService对应一个Endpoint。,如下: 

sun-jaxws.xml文件:



<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint name="hello" implementation="com.server.ws.impl.HelloWServiceImpl" url-pattern="/services/hello" />
</endpoints>


C.2、在web.xml中添加WSServlet,如果Web项目使用Servlet 3.0则不需要以下配置,如下:

web.xml文件:



<!-- JAXWS -->
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/services</url-pattern>
</servlet-mapping>
<!-- End JAXWS -->


打包成war,部署到tomcat,并启动tomcat,访问及结果如下:

JAX-WS(JWS)发布WebService_webservice_05

 

2.2、生成客户端

最后是客户端使用,由于WebService是平台和语言无关的基于xml的,所以我们完全可以使用不同语言来编写或生成客户端。

一般有三种方式来使用(对于Java语言而言):

一、使用jdk自带工具wsimport生成客户端:

  JAX-WS(JWS)发布WebService_webservice_06

  jdk自带的wsimport工具生成,上图我是把客户端文件生成到了桌面src文件中(-d),并保留了源文件(-keep),指定了包名(-p)。

  然后我们就可以使用生成的文件来调用服务器暴露的方法了:

 JAX-WS(JWS)发布WebService_webservice_07

值得一提的是你生成使用的jdk和你客户端的jre需要配套!

  从上面的目录结构我们可以发现:服务端的每个webmethod都被单独解析成为了一个类(如果使用了实体,实体也会被解析到客户端,并且是源码,所以建议使用实体时慎重)。

而我们的service则被生成了一个代理类来调用服务,接下来我们看看使用情况,在客户端调用服务:



package com.client;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;
import com.client.wsdl.hello.PersonEntity;

/**
* 调用WebService的客户端
*
*/
public class WSClient {

public static void main(String[] args) {
// 创建一个用于产生WebServiceImpl实例的工厂,WebServiceImplService类是wsimport工具生成的
HelloWSService factory = new HelloWSService();
// 通过工厂生成一个WebServiceImpl实例,WebServiceImpl是wsimport工具生成的
HelloWS wsImpl = factory.getHelloWSPort();
// 调用WebService的add方法
Integer resResult = wsImpl.add(10, 22);
System.out.println("调用WebService的add方法返回的结果是:" + resResult);
System.out.println("---------------------------------------------------");
// 调用WebService的save方法
PersonEntity pm = wsImpl.getPerson("孤傲苍狼", 123);
System.out.println("调用WebService的getPerson方法返回的结果是:" + pm.getName() + ",age=" + pm.getAge());
}
}


handler



package com.client.handler;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class AddAuthHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public boolean handleMessage(SOAPMessageContext context) {
// 判断消息是请求还是响应
Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

SOAPMessage message = context.getMessage();

if (output) {
try {
SOAPHeader header = message.getSOAPHeader();
if (header == null) {
header = message.getSOAPPart().getEnvelope().addHeader();
}

SOAPElement auth = header.addChildElement(new QName("http://www.client.com/auth", "auth"));

SOAPElement name = auth.addChildElement("name");
name.addTextNode("admin");

SOAPElement password = auth.addChildElement("password");
password.addTextNode("admin");

message.saveChanges();

} catch (SOAPException e) {
e.printStackTrace();
}
}

System.out.println(output ? "校验" : "不校验");
try {
message.writeTo(System.out);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("\r\n");

return true;
}

@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}

@Override
public void close(MessageContext context) {
}

@Override
public Set<QName> getHeaders() {
return null;
}
}


看看服务器的输出,我们是否调用成功:

JAX-WS(JWS)发布WebService_jax-ws_08

成功了!

2 client端的servlet方式

 



package com.client.servlet.hello;

import java.io.IOException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;


@WebServlet("/hello/add/servlet")
public class AddServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

public AddServlet() {
super();
}

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL wsdlUrl = new URL("http://localhost:8080/jaxwsserver-0.0.1-SNAPSHOT/services/hello?wsdl");
HelloWSService helloWSS = new HelloWSService(wsdlUrl);
HelloWS helloWS = helloWSS.getHelloWSPort();

Integer x = 3;
Integer y = 5;
Integer add = helloWS.add(x, y);

response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
response.getWriter().write(x.toString() + y.toString() + "=" + add.toString());
}

}


 

Ayncnow方法



package com.client.servlet.hello;

import java.io.PrintWriter;
import java.net.URL;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletResponse;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;

public class AsyncNowServletProcessor extends Thread {
private AsyncContext ac;

public AsyncNowServletProcessor(AsyncContext ac){
this.ac = ac;
}

public void run() {
HttpServletResponse response = (HttpServletResponse)ac.getResponse();
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");

try {
URL wsdlUrl = new URL("http://localhost:8080/jaxwsserver-0.0.1-SNAPSHOT/services/hello?wsdl");
HelloWSService helloWSS = new HelloWSService(wsdlUrl);
HelloWS helloWS = helloWSS.getHelloWSPort();
helloWS.now();
PrintWriter out = response.getWriter();
String now = helloWS.now().toGregorianCalendar().toString();
out.write(now);
out.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
ac.complete();
}
}

}


index方法



package com.client.servlet.hello;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;
import com.client.handler.AddAuthHandler;

/**
* Servlet implementation class IndexServlet
*/
@WebServlet("/hello/index/servlet")
public class IndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public IndexServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL wsdlUrl = new URL("http://localhost:8080/jaxwsserver-0.0.1-SNAPSHOT/services/hello?wsdl");
HelloWSService helloWSS = new HelloWSService(wsdlUrl);

//通过HandlerResolver添加Handler

helloWSS.setHandlerResolver(new HandlerResolver(){

@Override
@SuppressWarnings("rawtypes")
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(new AddAuthHandler());
return handlerChain;
}

});


HelloWS helloWS = helloWSS.getHelloWSPort();

response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
response.getWriter().write(helloWS.index());
}

}


now方法



package com.client.servlet.hello;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;

/**
* Servlet implementation class NowServlet
*/
@WebServlet(value = "/hello/now/servlet", asyncSupported = true)
public class NowServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public NowServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

URL wsdlUrl = new URL("http://localhost:8080/jaxwsserver-0.0.1-SNAPSHOT/services/hello?wsdl");
HelloWSService helloWSS = new HelloWSService(wsdlUrl);
HelloWS helloWS = helloWSS.getHelloWSPort();
String now = helloWS.now().toGregorianCalendar().toString();

response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
//new AsyncNowServletProcessor(null).start();


PrintWriter out = response.getWriter();

out.write(now);
out.flush();
/*
AsyncContext ac = request.startAsync(request, response);
ac.addListener(new AsyncListener(){

public void onComplete(AsyncEvent arg0) throws IOException {
}

public void onError(AsyncEvent arg0) throws IOException {
}

public void onStartAsync(AsyncEvent arg0) throws IOException {
}

public void onTimeout(AsyncEvent arg0) throws IOException {
}

}, request, response);

new AsyncNowServletProcessor(ac).start();
*/
}

}


person



package com.client.servlet.hello;

import java.io.IOException;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.client.wsdl.hello.HelloWS;
import com.client.wsdl.hello.HelloWSService;
import com.client.wsdl.hello.PersonEntity;

/**
* Servlet implementation class PersonServlet
*/
@WebServlet("/hello/person/servlet")
public class PersonServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/
public PersonServlet() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
*/
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
URL wsdlUrl = new URL("http://localhost:8080/jaxwsserver-0.0.1-SNAPSHOT/services/hello?wsdl");
HelloWSService helloWSS = new HelloWSService(wsdlUrl);
HelloWS helloWS = helloWSS.getHelloWSPort();

PersonEntity person = helloWS.getPerson("年龄", 18);

response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
response.getWriter().write("名字;" + person.getName() + ",年龄;" + person.getAge());
}

}