Apache CXF服务端SOAP与Restful接口编写规则

我们这里使用互联网上的项目作为示例程序。

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。

 

转载于:https://my.oschina.net/ososchina/blog/854162

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值