1.Customer
为了方便页面调用Restlet,需要在Customer类中加入id属性作为唯一标识,。
修改com.sunny.restlet.order.Customer类,代码如下:
package com.sunny.restlet.order; public class Customer { private String id; private String name; private String address; public Customer(String name, String address) { super(); this.name = name; this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getId() { return id; } public void setId(String id) { this.id = id; } @Override public String toString() { return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]"; } }
类中添加了id属性和getter/setter方法,修改了toString()方法。
2.OrderDaoImpl
因为Customer类中加入了id属性,所以要在add和update Customer前setId(custId)。
修改com.sunny.restlet.order.OrderDaoImpl类中的方法,代码如下:
public String addCustomer(Customer customer) { // TODO Auto-generated method stub String indexStr = String.valueOf(index++); customer.setId(indexStr); customers.put(indexStr, customer); return indexStr; } public void updateCustomerById(Customer customer, String custId) { // TODO Auto-generated method stub if (customers.get(custId) != null) { customer.setId(custId); customers.put(custId, customer); } }
代码中对addCustomer和updateCustomerById方法进行了修改。
3.Resource
我们需要修改下资源的各个方法,使得方法返回的数据符合json格式。
修改com.sunny.restlet.order.CustomersResource类中的方法,代码如下:
@Override protected Representation get() throws ResourceException { // TODO Auto-generated method stub Map customers = orderDao.getAllCustomers(); return new JsonRepresentation(new JSONObject(customers, false)); } @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) { new JsonRepresentation("{}"); } return new JsonRepresentation(customer); }
代码中修改了get方法,使返回数据为new JsonRepresentation(new JSONObject(customers, false)),因为new JsonRepresentation(customers)不能很好的解析map中的对象。
post方法也进行了修改,当customer为空时返回new JsonRepresentation("{}"),否则json解析器会报错。
修改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("{\"message\":\"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 new JsonRepresentation("{}"); } 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 new JsonRepresentation("{}"); } return new JsonRepresentation(customer); }
代码中修改了get和put方法,当customer为空时返回new JsonRepresentation("{}"),否则json解析器会报错。
delete方法也进行了修改,返回符合json格式的提示信息new JsonRepresentation("{\"message\":\"success\"}")。
4.jQuery
本次实践要在页面上使用javascript+ajax访问Restlet资源,最方便的当然是用jQuery库了,这里我使用的是1.2.6版本的jquery.pack.js,其他新版本也可以使用。
在WebRoot/目录下创建lib文件夹,将jquery.pack.js拷贝至该文件夹中。
5.页面
因为使用javascript来访问资源和页面展示,完全不需要服务端代码实现,所以这次使用html文件就行了。
在WebRoot/目录下创建list.html,代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <script type="text/javascript" src="lib/jquery.pack.js"></script> <script type="text/javascript"> // 初始化函数,加载customers并显示,list $(function(){ $.ajax({ url: 'spring/customers', type: 'GET', dataType: 'json', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(data){ $.each(data, function(key, value){ var row = $("#template").clone(); row.find("#id").text(value.id); row.find("#name").text(value.name); row.find("#address").text(value.address); row.find("#operation").html("<a href='javascript:void(0);' id='operation"+ value.id + "' onclick='read(\""+value.id+"\");'>update</a> <a href='javascript:void(0);' onclick='deleteCustomer(\""+value.id+"\");'>delete</a>"); row.attr("id","customer"+value.id); row.appendTo("#tbody"); }); } }); }); // 显示新增界面 function create_show(){ if($("#create").css("display")=="none"){ $("#create").css("display","block"); }else{ $("#create").css("display","none"); } } // 新增,create function create(){ $.ajax({ url: 'spring/customers', type: 'POST', data:{ name:$('#create_name').val(), address:$('#create_address').val() }, dataType: 'json', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(data){ if(data.id==undefined){ alert("Error add customer"); }else{ var row = $("#template").clone(); row.find("#id").text(data.id); row.find("#name").text(data.name); row.find("#address").text(data.address); row.find("#operation").html("<a href='javascript:void(0);' id='operation"+ data.id + "' onclick='read(\""+data.id+"\");'>update</a> <a href='javascript:void(0);' onclick='deleteCustomer(\""+data.id+"\");'>delete</a>"); row.attr("id","customer"+data.id); row.appendTo("#tbody"); } $("#create").css("display","none"); } }); } // 查询,read function read(id){ if($("#update").css("display")=="none"){ $.ajax({ url: 'spring/customers/'+id, type: 'GET', dataType: 'json', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(data){ if(data.id==undefined){ alert("no customer " + id); $("#customer"+id).remove(); }else{ var offset = $("#operation"+id).offset(); var height = $("#operation"+id).height(); $("#update").css("top", offset.top + height); $("#update").css("left", offset.left); $("#update_id").val(data.id); $("#update_name").val(data.name); $("#update_address").val(data.address); $("#update").css("display","block"); } } }); }else{ $("#update").css("display","none"); } } // 修改,update function update(){ $.ajax({ url: 'spring/customers/'+$('#update_id').val(), type: 'PUT', data:{ name:$('#update_name').val(), address:$('#update_address').val() }, dataType: 'json', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(data){ if(data.id==undefined){ alert("no customer " + $('#update_id').val()); $("#customer"+$('#update_id').val()).remove(); }else{ var row = $("#customer"+data.id); row.find("#name").text(data.name); row.find("#address").text(data.address); row.find("#operation").html("<a href='javascript:void(0);' id='operation"+ data.id + "' onclick='read(\""+data.id+"\");'>update</a> <a href='javascript:void(0);' onclick='deleteCustomer(\""+data.id+"\");'>delete</a>"); row.attr("id","customer"+data.id); } $("#update").css("display","none"); } }); } // 删除,delete function deleteCustomer(id){ $.ajax({ url: 'spring/customers/'+id, type: 'DELETE', dataType: 'json', timeout: 1000, error: function(){ alert('Error loading XML document'); }, success: function(data){ if(data.message!="success"){ alert("Error deleting customer" + id); }else{ $("#customer"+id).remove(); } } }); } </script> </head> <body> <a href="javascript:void(0);" onclick="create_show();">create</a> <!-- 新增界面 --> <div id="create" style="position:absolute; z-index:2; width:180px; height:150px; display:none; background-color:gray"> name: <input type="text" id="create_name"> <br> address: <input type="text" id="create_address"> <br> <input type="button" id="create_button" value="create" onclick="create();"> <input type="button" id="create_cancel" value="cancel" onclick="create_show();"> </div> <!-- 修改界面 --> <div id="update" style="position:absolute; z-index:2; width:180px; height:150px; display:none; background-color:blue"> name: <input type="hidden" id="update_id"> <input type="text" id="update_name"> <br> address: <input type="text" id="update_address"> <br> <input type="button" id="update_button" value="update" onclick="update();"> <input type="button" id="update_cancel" value="cancel" onclick="read(0);"> </div> <div id="list"> <table border="1" cellspacing="0"> <thead> <tr> <th>id</th> <th>name</th> <th>address</th> <th>operation</th> </tr> </thead> <tbody id="tbody"> <tr id="template"> <td id="id"></td> <td id="name"></td> <td id="address"></td> <td id="operation"></td> </tr> </tbody> </table> </div> </body> </html>
- 页面加载时访问/customers的get方法读取现有Customers并展示,实现list。
- 点击create链接时调用create_show()弹出新增Customer界面,提交后调用create()访问/customers的post方法,并将返回结果添加在表格最下方,实现create。
- 点击update链接时调用read(id)查询Customer并展示在修改Customer界面,提交后调用update()访问/customer的put方法,并将返回结果修改至原来所在行,实现read和update。
- 点击delete链接时调用deleteCustomer(id)删除Customer,并将原来所在行删除,实现delete。
6.测试
部署程序后,使用浏览器访问 http://localhost:8080/firstSteps/list.jsp,可以看到空的表格和create链接。
依次进行create>read>update>delete操作,可以看到增删改查没有问题,说明使用javascript和ajax对Restlet资源的访问成功。
新开一个页面并将某个Customer删除后,在原来的页面中尝试read、update和delete操作,可以看到提示"no customer 0"信息,说明Restlet返回的new JsonRepresentation("{}")被成功解析为json数据。
7.Application
在本次实践中我们并没有使用html form配合method参数来访问资源的put和delete方法,而是使用jQuery提供的$.ajax方法中的参数type: 'PUT'和type: 'DELETE'来实现,所以第六章中对Application的配置就不是必须的了。
修改src/目录下的applicationContext.xml,代码如下:
<!-- component --> <bean id="component" class="org.restlet.ext.spring.SpringComponent"> <property name="defaultTarget" ref="restRouter" /> </bean> <!-- application --> <!-- <bean id="application" class="com.sunny.restlet.order.CustomerApplication"> <lookup-method name="createRoot" bean="restRouter" /> </bean> -->
代码中仅注释掉application配置,并将component的defaultTarget引用指向restRouter,其他配置保持不变。这样spring就回到了第五章时的相同配置。
重新部署程序后进行测试,提示信息和效果保持不变,说明Application的配置删除成功。
应支持我的朋友要求,上传源码工程。