虽然webService为我们提供了很大的便利,但其也不是万能的,比方说对于Map类型的数据,它是无法处理的,这时候就需要我们进行手工处理了。在此处我们用的是转换工具类FKXmlAdapter。下面我们看具体的实现步骤:
1、用到的实体类如下:
package com.tgb.web.domain;
public class Cat {
private Integer id;
private String name;
private String color;
//get/set方法省略
public Cat(){}
public Cat(Integer id, String name, String color) {
super();
this.id = id;
this.name = name;
this.color = color;
}
}
public class User {
private Integer id;
private String name;
private String pass;
private String address;
//get/set方法省略
public User(){}
public User(Integer id, String name, String pass, String address) {
super();
this.id = id;
this.name = name;
this.pass = pass;
this.address = address;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((pass == null) ? 0 : pass.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (pass == null) {
if (other.pass != null)
return false;
} else if (!pass.equals(other.pass))
return false;
return true;
}
}
2、服务层接口及其实现
1)UserService
public interface UserService {
public List<Cat> getCatsByUser(User user);
//CXF无法处理该类型:Map<String, Cat>
public Map<String, Cat> getAllCats();
}
2)UserServiceImpl
public class UserServiceImpl implements UserService {
//用一个HashMap来模拟内存中的数据库
static Map<User, List<Cat>> catDb=new HashMap<User, List<Cat>>();
static{
List<Cat> catList1=new ArrayList<Cat>();
catList1.add(new Cat(1,"garfield","橙色"));
catList1.add(new Cat(2,"机器猫","橙色"));
catDb.put(new User(1,"sun","3322","花果山"), catList1);
List<Cat> catList2=new ArrayList<Cat>();
catList2.add(new Cat(3,"ketty","白色"));
catList2.add(new Cat(4,"熊猫","白黑色"));
catDb.put(new User(2,"zhu","5629","高老庄"), catList2);
}
@Override
public List<Cat> getCatsByUser(User user) {
return catDb.get(user);
}
@Override
public Map<String, Cat> getAllCats() {
Map<String, Cat> result=new HashMap<String, Cat>();
int i=1;
for (List<Cat> cats :catDb.values()){
for(Cat cat:cats){
result.put("第"+ i++ +"个", cat);
}
}
return result;
}
}
3、 webService接口及其实现
1)HelloWorld
@WebService
public interface HelloWorld {
public String sayHi(String str);
public List<Cat> getCatsByUser(User user);
//此注释含义:<span style="color:#FF0000;">利用转换工具类FKXmlAdapter,将Map<String, Cat>类型转换成其他可以访问的类型值返回</span>
@XmlJavaTypeAdapter(FKXmlAdapter.class)
public Map<String, Cat> getAllCats();
}
2)HelloWorldWs
@WebService(endpointInterface="com.tgb.web.webservice.HelloWorld",serviceName="HelloWorld")
public class HelloWorldWs implements HelloWorld {
@Override
public String sayHi(String str) {
return "hello,"+str+",现在时间是:"+new Date();
}
@Override
public List<Cat> getCatsByUser(User user) {
UserService us=new UserServiceImpl();
return us.getCatsByUser(user);
}
@Override
public Map<String, Cat> getAllCats() {
UserService us=new UserServiceImpl();
return us.getAllCats();
}
}
4、 转换工具类 FKXmlAdapter ( 该转换器负责完成StringCat与Map<String, Cat>类型之间的相互转换 )
1)FKXmlAdapter 转换工具类
//该转换器负责完成StringCat与Map<String, Cat>类型之间的相互转换
public class FKXmlAdapter extends XmlAdapter<StringCat, Map<String, Cat>>{
@Override
public Map<String, Cat> unmarshal(StringCat v) throws Exception {
Map<String, Cat> result= new HashMap<String, Cat>();
for (Entry entry:v.getEntries()) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
@Override
public StringCat marshal(Map<String, Cat> v) throws Exception {
StringCat sc=new StringCat();
List<Entry> entryList=new ArrayList<StringCat.Entry>();
for(String key:v.keySet()){
Entry entry=new Entry();
entry.setKey(key);
entry.setValue(v.get(key));
entryList.add(entry);
}
sc.setEntries(entryList);
return sc;
}
}
2)要转换的类型StringCat
public class StringCat {
public static class Entry{
private String key;
private Cat value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Cat getValue() {
return value;
}
public void setValue(Cat value) {
this.value = value;
}
}
private List<Entry> entries;
public List<Entry> getEntries() {
return entries;
}
public void setEntries(List<Entry> entries) {
this.entries = entries;
}
}
5、 发布webService
public class ServerMain {
public static void main(String[] args) {
HelloWorld hw=new HelloWorldWs();
//调用Endpoint的publish方法发布Web Service
Endpoint.publish("http://192.168.0.72:8088/HelloWorld", hw);
System.out.println("webService 发布成功!");
}
}
6、在浏览器中可以访问到发布的webService:http://192.168.0.72:8088/HelloWorld?wsdl
=================================================================================================================
在上面我们已经将webService的服务端写好,下面我们在客户端写测试程序来测试我们发布的服务了,如下:
public class ClientMain {
public static void main(String[] args) {
HelloWorld factory=new HelloWorld();
com.tgb.web.webservice.HelloWorld hWorld= factory.getHelloWorldWsPort();
System.out.println(hWorld.sayHi("张三"));
System.out.println("===================================================");
User user=new User();
user.setId(30);
user.setName("sun");
user.setPass("3322");
List<Cat> cats=hWorld.getCatsByUser(user);
for(Cat cat :cats){
System.out.println(cat.getName());
}
System.out.println("===================================================");
//调用CXF处理过的类型方法
StringCat SC=hWorld.getAllCats();
for(Entry entry:SC.getEntries()){
System.out.println(entry.getKey()+"-"+entry.getValue().getName());
}
}
}