我们这里使用互联网上的项目作为示例程序。
SOAP WebService接口编写
1,接口的编写
@WebService(endpointInterface="com.tgb.service.HelloWorld",serviceName="HelloWorld" )
public interface HelloWorld{
@WebResult(name = "result") //返回值名称
@WebMethod(action="sayHi") //发布到外面的公开,action表示该方法的soapAction,默认是空,这里为了兼容SOAP1.1,手动写上soapAction的名称
@POST //请求时要使用HTTP POST Method
public String sayHi(@WebParam(name="msg") String name);
@WebResult(name = "userList")//返回值名称
@WebMethod(action="getCatsByUser")
@POST
public List<Cat> getCatsByUser(@WebParam(name="use")User user);
@WebResult(name = "nameKeyCatValue")
@WebMethod(action="getAllCats")
@GET //请求时要使用HTTP GETMethod
public Map<String,Cat> getAllCats();
}
2.实现类的编写
public class HelloWorldImpl implements HelloWorld{
@Autowired
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public String sayHi( String name) {
return name+"您好!现在时间为:"+new Date();
}
@Override
public List<Cat> getCatsByUser(User user) {
return userService.getCatsByUser(user);
}
@Override
public Map<String, Cat> getAllCats() {
return userService.getAllCats();
}
}
3.对象Entity的编写
package com.tgb.domain;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlType;
@XmlType(name = "user", propOrder = { "id", "name", "address", "pass", "card" })
public class User {
private Integer id;
private String name;
private String pass;
private String address;
private Card card;
@XmlEnum(String.class)
// 声明枚举
public enum Card {
CLUBS, DIAMONDS, HEARTS, SPADES
};
public User() {
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public User(Integer id, String name, String pass, String address) {
super();
this.id = id;
this.name = name;
this.pass = pass;
this.address = address;
this.card = Card.CLUBS;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
// 即认为只要name和address相同,就是同一个对象
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((name == null) ? 0 : name.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 (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
4.常用的注解
@XMLElement - 将java属性声明成xml元素
@XmlAttribute - 将java属性声明成xml属性
@XmlID - xml对象Entity中id声明称xml属性
@XmlRootElement -默认javaBean的注解
5.AbstractPhaseInterceptor编写
//通过PhaseInterceptor,可以指定拦截器在哪个阶段起作用
public class AuthInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
//由于AbstractPhaseInterceptor无无参数构造器,使用继承的方式,需要显示调用父类有参数的构造器
public AuthInterceptor(){
//super表示显示调用父类有参数的构造器
//显示调用父类构造器之后,程序将不会隐式调用父类无参数的构造器
super(Phase.PRE_INVOKE);//该拦截器将会调用之前拦截SOAP消息
}
//实现自己的拦截器时,需要实现handleMessage方法。
//handleMessage方法中的形参就是被拦截到的Soap消息
//一旦程序获取了SOAP消息,剩下的事情就可以解析SOAP消息或修改SOAP消息
@Override
public void handleMessage(SoapMessage msg) throws Fault {
System.out.println("-------"+msg);
//从这里可以看出,我们已经拦截到了SOAP消息
//得到SOAP消息所有Header
List<Header> headers=msg.getHeaders();
//如果没有Header
if(headers==null||headers.size()<1){
throw new Fault(new IllegalArgumentException("根本没有Header,不能调用"));
}
//假如要求第一个Header携带了用户名,密码信息
Header firstHeader=headers.get(0);
Element ele=(Element)firstHeader.getObject();
NodeList userIds=ele.getElementsByTagName("userId");
NodeList userPasses=ele.getElementsByTagName("userPass");
if(userIds.getLength()!=1){
throw new Fault(new IllegalArgumentException("用户名的格式不正确!"));
}
if(userPasses.getLength()!=1){
throw new Fault(new IllegalArgumentException("密码的格式不正确!"));
}
//得到第一个userId元素里的文本内容,以该内容作为用户名字
String userId=userIds.item(0).getTextContent();
String userPass=userPasses.item(0).getTextContent();
//实际项目中,应该去查询数据库,该用户名密码是否被授权调用web service
if(!userId.equals("admin") || !userPass.equals("password123")){
throw new Fault(new IllegalArgumentException("用户名密码不正确!"));
}
}
@Override
public void handleFault(SoapMessage message) {
super.handleFault(message);
System.out.println(message);
}
}
Restful WebService接口编写
接口服务类
@Path("/rest")
public interface MyRestfulService {
@Path("/add/{x}/{y}")
@GET
@Produces({ MediaType.APPLICATION_JSON +";charset=UTF-8"})
public Map<String,String> add(@PathParam("x")int i,@PathParam("y")int y);
@POST
@Path("/sayHi/{msg}")
@Produces({MediaType.APPLICATION_JSON +";charset=UTF-8"})
public Map<String, String> put(@PathParam("msg")String id);
}
JAX-RS标注
JAX-RS提供了一些标注将一个资源类,一个POJO类,封装为Web资源。标注包括:
@Path,标注资源类或方法的相对路径
@GET,@PUT,@POST,@DELETE,标注方法是用的HTTP请求的类型,分别对应 4 种 HTTP 方法,用于对资源进行创建、检索、更新和删除的操作。
- 若要创建资源,应该使用 POST 方法;
- 若要检索某个资源,应该使用 GET 方法;
- 若要更改资源状态或对其进行更新,应该使用 PUT 方法;
- 若要删除某个资源,应该使用 DELETE 方法。
@Produces,标注返回的MIME媒体类型
@Consumes,标注可接受请求的MIME媒体类型
@PathParam,@QueryParam,@HeaderParam,@CookieParam,@MatrixParam,@FormParam,分别标注方法的参数来自于HTTP请求的不同位置,
- @PathParam来自于URL的路径,
- @QueryParam来自于URL的查询参数,
- @HeaderParam来自于HTTP请求的头信息,
- @CookieParam来自于HTTP请求的Cookie。