Restlet 2.0 边学边写(七)Restlet返回xml和json数据格式

上一次实践实现了htmlform来访问Restlet的PUT和DELETE方法,但返回数据都是string,仅能作为演示使用。本次实践将使各方法返回xml和json格式的数据,方便页面、程序的读取和展示。

1.xml库

首先是基础的xml数据格式。Restlet的扩展包org.restlet.ext.xml.jar提供各种xml相关类库。包中的抽象类XmlRepresentation作为父类提供接口和方法,但不能创建该父类的实例,而是需要使用SaxRepresentation和DomRepresentation类的实例来执行操作。

将Restlet安装目录\EditionJavaEE\2.0.10\lib下的org.restlet.ext.xml.jar包加入BuildPath。

2.Resource

修改com.sunny.restlet.order.CustomersResource类,代码如下:

@Override
	protected Representation get() throws ResourceException {
		// TODO Auto-generated method stub
		Map customers = orderDao.getAllCustomers();
		DomRepresentation representation;
		try {
			representation = new DomRepresentation();
			Document dom = representation.getDocument();
			Element all = dom.createElement("customers");
			dom.appendChild(all);
			for (Object object : customers.entrySet()) {
				Entry<String, Customer> entry = (Entry) object;
				String id = entry.getKey();
				Customer customer = entry.getValue();
				Element root = dom.createElement("customer");
				root.setAttribute("id", id);
				all.appendChild(root);
				Element namElement = dom.createElement("name");
				namElement.appendChild(dom.createTextNode(customer.getName()));
				root.appendChild(namElement);
				Element addressElement = dom.createElement("address");
				addressElement.appendChild(dom.createTextNode(customer
						.getAddress()));
				root.appendChild(addressElement);
			}
			dom.normalizeDocument();
			return representation;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	protected Representation post(Representation entity)
			throws ResourceException {
		// TODO Auto-generated method stub
		Form form = new Form(entity);
		String name = form.getFirstValue("name");
		String address = form.getFirstValue("address");
		Customer customer = new Customer(name, address);
		String id = orderDao.addCustomer(customer);
		customer = orderDao.getCustomerById(id);
		if (customer == null) {
			return null;
		}
		DomRepresentation representation;
		try {
			representation = new DomRepresentation();
			Document dom = representation.getDocument();
			Element root = dom.createElement("customer");
			root.setAttribute("id", id);
			dom.appendChild(root);
			Element namElement = dom.createElement("name");
			root.appendChild(namElement);
			namElement.appendChild(dom.createTextNode(customer.getName()));
			Element addressElement = dom.createElement("address");
			root.appendChild(addressElement);
			addressElement.appendChild(dom
					.createTextNode(customer.getAddress()));
			dom.normalizeDocument();
			return representation;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

类中将/customers资源的get和post方法返回的Representation修改为DomRepresentation,并创建dom文件来格式化数据。

修改com.sunny.restlet.order.CustomerResource类,代码如下:

@Override
	protected Representation delete() throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		orderDao.deleteCustomerById(customerId);
		DomRepresentation representation;
		try {
			representation = new DomRepresentation();
			Document dom = representation.getDocument();
			Element root = dom.createElement("message");
			dom.appendChild(root);
			root.appendChild(dom.createTextNode("success"));
			dom.normalizeDocument();
			return representation;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	protected Representation get() throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		Customer customer = orderDao.getCustomerById(customerId);
		if (customer == null) {
			return null;
		}
		DomRepresentation representation;
		try {
			representation = new DomRepresentation();
			Document dom = representation.getDocument();
			Element root = dom.createElement("customer");
			root.setAttribute("id", customerId);
			dom.appendChild(root);
			Element namElement = dom.createElement("name");
			root.appendChild(namElement);
			namElement.appendChild(dom.createTextNode(customer.getName()));
			Element addressElement = dom.createElement("address");
			root.appendChild(addressElement);
			addressElement.appendChild(dom
					.createTextNode(customer.getAddress()));
			dom.normalizeDocument();
			return representation;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	protected Representation put(Representation entity)
			throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		Form form = new Form(entity);
		String name = form.getFirstValue("name");
		String address = form.getFirstValue("address");
		Customer customer = new Customer(name, address);
		orderDao.updateCustomerById(customer, customerId);
		customer = orderDao.getCustomerById(customerId);
		if (customer == null) {
			return null;
		}
		DomRepresentation representation;
		try {
			representation = new DomRepresentation();
			Document dom = representation.getDocument();
			Element root = dom.createElement("customer");
			root.setAttribute("id", customerId);
			dom.appendChild(root);
			Element namElement = dom.createElement("name");
			root.appendChild(namElement);
			namElement.appendChild(dom.createTextNode(customer.getName()));
			Element addressElement = dom.createElement("address");
			root.appendChild(addressElement);
			addressElement.appendChild(dom
					.createTextNode(customer.getAddress()));
			dom.normalizeDocument();
			return representation;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

类中将/customer/{custId}的资源的get、put和delete方法返回的Representation修改为DomRepresentation,并创建dom文件来格式化数据。

3.测试

部署程序后,使用浏览器访问http://localhost:8080/firstSteps/,并将页面上的五个链接在新页面中打开访问。

在post.jsp中输入[name=0,address=0]并提交form,可以看到提示信息

  • <?xmlversion="1.0"encoding="UTF-8"?>
  • <customerid="0">
  • <name>0</name>
  • <address>0</address>
  • </customer>

说明调用post方法访问/customers返回xml数据成功,数据被新增。

再次在post.jsp中输入[name=1,address=1]并提交form,刷新getcustomers"链接页面,可以看到提示信息

  • <?xmlversion="1.0"encoding="UTF-8"?>
  • <customers>
  • <customerid="0">
  • <name>0</name>
  • <address>0</address>
  • </customer>
  • <customerid="1">
  • <name>1</name>
  • <address>1</address>
  • </customer>
  • </customers>

说明调用get方法访问/customers返回xml数据成功。

在put.jsp中输入[id=0,name=00,address=00]并提交form,可以看到提示信息

  • <?xmlversion="1.0"encoding="UTF-8"?>
  • <customerid="0">
  • <name>00</name>
  • <address>00</address>
  • </customer>

说明调用put方法访问/customer/{custId}返回xml数据成功,数据被修改。

在get.jsp中输入[id=0]并提交form,可以看到提示信息同上。说明调用get方法访问/customer/{custId}返回xml数据成功。

在delete.jsp中输入[id=0]并提交form,可以看到提示信息

  • <?xmlversion="1.0"encoding="UTF-8"?>
  • <message>success</message>

刷新getcustomers"链接页面,可以看到提示信息

  • <?xmlversion="1.0"encoding="UTF-8"?>
  • customers>
  • <customerid="1">
  • <name>1</name>
  • <address>1</address>
  • </customer>
  • </customers>

说明调用delete方法访问/customer/{custId}返回xml数据成功,数据被删除。

4.使用ClientResource测试

下面我们使用第五节中用到的ClientResource客户端方式调用Restlet服务。

修改com.sunny.restlet.order.CustomerResource类,代码如下:

public static void main(String[] args) {
		// TODO Auto-generated method stub

		try {
			ClientResource clientCustomers = new ClientResource(
					"http://localhost:8080/firstSteps/spring/customers");
			ClientResource clientCustomer = new ClientResource(
					"http://localhost:8080/firstSteps/spring/customers/0");
			Form form = new Form();
			form.add("name", "b");
			form.add("address", "b");
			Representation representation = clientCustomers.post(form);
			System.out.println(representation.getText());
			representation = clientCustomers.get();
			System.out.println(representation.getText());
			form.clear();
			form.add("name", "c");
			form.add("address", "c");
			representation = clientCustomer.put(form);
			System.out.println(representation.getText());
			representation = clientCustomer.get();
			System.out.println(representation.getText());
			representation = clientCustomer.delete();
			System.out.println(representation.getText());
			representation = clientCustomers.get();
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

重新部署firstSteps后,运行Test类,在控制台可以看到输出信息

  • 2013-1-616:45:29org.restlet.engine.http.connector.HttpClientHelperstart
  • 信息:StartingthedefaultHTTPclient
  • <?xmlversion="1.0"encoding="UTF-8"?><customerid="0"><name>b</name><address>b</address></customer>
  • <?xmlversion="1.0"encoding="UTF-8"?><customers><customerid="0"><name>b</name><address>b</address></customer></customers>
  • 2013-1-616:45:29org.restlet.engine.http.connector.HttpClientHelperstart
  • 信息:StartingthedefaultHTTPclient
  • <?xmlversion="1.0"encoding="UTF-8"?><customerid="0"><name>c</name><address>c</address></customer>
  • <?xmlversion="1.0"encoding="UTF-8"?><customerid="0"><name>c</name><address>c</address></customer>
  • <?xmlversion="1.0"encoding="UTF-8"?><message>success</message>
  • <?xmlversion="1.0"encoding="UTF-8"?><customers/>

说明客户端方式调用成功。

5.json库

Json作为现在通用的互联网数据传输格式,Restlet当然要支持的了。Restlet的扩展包org.restlet.ext.json.jar提供各种xml相关类库。包中的JsonRepresentation类可以作为返回数据载体使用,其中对多种数据类型提供了支持。

将Restlet安装目录\EditionJavaEE\2.0.10\lib下的org.restlet.ext.json.jar包和org.json.jar包加入BuildPath。

6.Resource

修改com.sunny.restlet.order.CustomersResource类,代码如下:

@Override
	protected Representation get() throws ResourceException {
		// TODO Auto-generated method stub
		Map customers = orderDao.getAllCustomers();
		return new JsonRepresentation(customers);
	}

	@Override
	protected Representation post(Representation entity)
			throws ResourceException {
		// TODO Auto-generated method stub
		Form form = new Form(entity);
		String name = form.getFirstValue("name");
		String address = form.getFirstValue("address");
		Customer customer = new Customer(name, address);
		String id = orderDao.addCustomer(customer);
		customer = orderDao.getCustomerById(id);
		if (customer == null) {
			return null;
		}
		return new JsonRepresentation(customer);	
	}

类中将/customers资源的get和post方法返回的Representation修改为JsonRepresentation。

修改com.sunny.restlet.order.CustomerResource类,代码如下:

@Override
	protected Representation delete() throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		orderDao.deleteCustomerById(customerId);
		return new JsonRepresentation("success");
	}

	@Override
	protected Representation get() throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		Customer customer = orderDao.getCustomerById(customerId);
		if (customer == null) {
			return null;
		}
		return new JsonRepresentation(customer);
	}

	@Override
	protected Representation put(Representation entity)
			throws ResourceException {
		// TODO Auto-generated method stub
		String customerId = (String) getRequest().getAttributes().get("custId");
		Form form = new Form(entity);
		String name = form.getFirstValue("name");
		String address = form.getFirstValue("address");
		Customer customer = new Customer(name, address);
		orderDao.updateCustomerById(customer, customerId);
		customer = orderDao.getCustomerById(customerId);
		if (customer == null) {
			return null;
		}
		return new JsonRepresentation(customer);
	}

类中将/customer/{custId}的资源的get、put和delete方法返回的Representation修改为JsonRepresentation。可以看到JsonRepresentation对各数据类型的支持。

7.测试

重新部署firstSteps后,运行Test类,在控制台可以看到输出信息

  • 2013-1-617:32:20org.restlet.engine.http.connector.HttpClientHelperstart
  • 信息:StartingthedefaultHTTPclient
  • {"address":"b","name":"b"}
  • {"0":"Customer[name=b,address=b]"}
  • 2013-1-617:32:21org.restlet.engine.http.connector.HttpClientHelperstart
  • 信息:StartingthedefaultHTTPclient
  • {"address":"c","name":"c"}
  • {"address":"c","name":"c"}
  • success
  • {}

说明客户端方式调用资源,返回json数据成功。

同样可以通过页面来访问修改后的程序,但是返回会是个文件,下载打开后内容和上面的提示信息类似。

8.思考

我们也可以简单的使用StringRepresentation来达到相同的效果,但是需要自己在代码中调用Dom4J和JSON类库来生成json和xml字符串,再使用StringRepresentation将结果返回。