webservice学习 4.JAX-RS简单使用 以及message body writer错误解决[CXF 2.7.4]

JAX-RS实际做起来还是蛮简单的.

JAX-RS和JAX-WS的不同之处吧

个人觉得是

JAX-RS更在意资源的位置  通过定义Path来寻找资源 而获取资源这个动作则是透明的

而JAX-WS是执行一个动作来获取资源 他对资源的位置是不知道的

这是两种不同的思路 JAX-RS有一种把资源通过资源的位置公开的直感 而JAX-WS是把使用的方法给公开

以上只是自己的想法 初学webservice 如果理解错了欢迎指正下.

首先提提操作过程中出现的一个错误

ID: 1
Response-Code: 500
Content-Type: text/plain
Headers: {Date=[Mon, 20 May 2013 15:19:49 GMT]}
Payload: No message body writer has been found for response class ArrayList.

使用了以下路径:

http://localhost:8888/produce/manu?manu=cc

 对应的方法是:

	@GET
	@Path("/manu")
//	@Produces("application/xml")
	public List<Product> getByManufacture(@QueryParam("manu") String manufacture);

 网上说是要对List重新封装下 用@XmlRootElement注解解决下

后来我发现只要把注释那边打开就可以了 加上一个Produces 告知产生的是什么类型(还可以是application/json等)

修改后显示正常了:

<Products>
<Product id="1" name="pt">
<price>12.2</price>
<createTime>2013-05-20T22:41:53.489+08:00</createTime>
<count>5</count>
<manufacturer>cc</manufacturer>
<phoneNumber>123456</phoneNumber>
</Product>
</Products>

这里说明下笔者使用的版本是:CXF 2.7.4 

其实这个问题产生还是因为通过的是浏览器直接打开吧 用HttpComponent组件直接连接是不会产生的

不过实际使用还是指定一下比较好 而且可以通过指定不同的类型来通过path的设定返回不同的格式.

关于Produces的更多资料参阅:

写道
http://docs.oracle.com/javaee/6/api/javax/ws/rs/Produces.html

好了接下来是操作步骤:

首先是对实体类进行操作 涉及到一些JAXB的注解(忽略掉JPA的注解吧):

package org.cc.rs.vo;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Product")
@Entity
@XmlAccessorType(XmlAccessType.FIELD)
public class Product {

	@Id
	@GeneratedValue
	@Column(name="id")
	@XmlAttribute(name="id")
	private int id;
	
	@Column(unique=true,nullable=false)
	@XmlAttribute(name="name")
	private String name;
	
	@XmlElement(name="price")
	private double price;
	
	@XmlElement(name="createTime")
	private Date createTime;
	
	@XmlElement(name="count")
	private int count;

	@XmlElement(name="manufacturer")
	private String manufacturer;
	
	@XmlElement(name="phoneNumber")
	private String phoneNumber;

        省略getter和setter... 
        ... ...

	@Override
	public String toString() {
		return "Product [id=" + id + ", name=" + name + ", price=" + price
				+ ", createTime=" + createTime + ", count=" + count
				+ ", manufacturer=" + manufacturer + ", phoneNumber="
				+ phoneNumber + "]";
	}
	
	
}

第一步完成了 我们要传输的资源的格式也规定好了

那么接下来就是把这个资源放出去 可以让外界通过位置来找寻:

这边简单起见就写了两个方法:

package org.cc.rs.service;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.cc.rs.vo.Product;

@Path("/produce/")
public interface IProductService {

	// http://localhost:8888/produce/name?name=pt
	@GET
	@Path("/name")
	@Produces("application/xml")
	public Product getByName(@QueryParam("name") String name);
	
	// http://localhost:8888/produce/manu?manu=cc
	@GET
	@Path("/manu")
	@Produces("application/xml")
	public List<Product> getByManufacture(@QueryParam("manu") String manufacture);
}

 ok 位置也确定好后 接下来就是发布了:

package org.cc.rs.server;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.cc.rs.service.impl.ProductServicce;

public class Server {

	public static void main(String[] args) {

		JAXRSServerFactoryBean bean=new JAXRSServerFactoryBean();
		bean.getInInterceptors().add(new LoggingInInterceptor());
		bean.getOutInterceptors().add(new LoggingOutInterceptor());
		bean.setResourceClasses(ProductServicce.class);
		bean.setAddress("http://localhost:8888/");
		bean.create();
	}
}

 浏览器输入地址就可以看见结果了

如果哪里说错了 谢谢指正 刚学了一段时间 基础什么的都不是很扎实.

猜你喜欢

转载自fair-jm.iteye.com/blog/1872455