Restlet 2.0 边学边写(六)使用html form访问Restlet的PUT和DELETE

上一次实践实现了POST、PUT和DELETE方法,并使用htmlform访问了POST和GET方法,本次实践将使用htmlform来访问PUT和DELETE方法。

参考:http://ajaxcn.iteye.com/blog/434449

1.html

修改WebRoot/目录下的index.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
	</head>

	<body>
		<a href="/firstSteps/spring/customers">get customers</a>
		<a href="post.jsp">post customers</a>
		<a href="get.jsp">get customer</a>
		<a href="put.jsp">put customer</a>
		<a href="delete.jsp">delete customer</a>
	</body>
</html>

页面上的链接对应了上一次实践创建的各个资源的访问方法。

在WebRoot/目录下新建post.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
	</head>

	<body>
		<form action="/firstSteps/spring/customers" method="post">
			name:
			<input type="text" name="name">
			<br>
			address:
			<input type="text" name="address">
			<br>
			<input type="submit" value="submit">
		</form>
	</body>
</html>

页面会将form中的信息post到/firstSteps/spring/customers。

在WebRoot/目录下新建get.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<script type="text/javascript">
			function getCustomer(){
				document.getElementById("form").action="/firstSteps/spring/customers/"+document.getElementById("id").value;
				document.getElementById("form").submit();
			}
		</script>
	</head>

	<body>
		<form action="/firstSteps/spring/customers/0" method="get" name="form" id="form">
			id:
			<input type="text" name="id" id="id">
			<br>
			<input type="button" value="submit" onclick="getCustomer();">
		</form>
	</body>
</html>

页面会使用get方式访问/firstSteps/spring/customers/{custId}。

在WebRoot/目录下新建put.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<script type="text/javascript">
			function putCustomer(){
				document.getElementById("form").action="/firstSteps/spring/customers/"+document.getElementById("id").value+"?method=put";
				document.getElementById("form").submit();
			}
		</script>
	</head>

	<body>
		<form action="/firstSteps/spring/customers/0?method=put" method="post" name="form" id="form">
			id:
			<input type="text" name="id" id="id">
			<br>
			name:
			<input type="text" name="name">
			<br>
			address:
			<input type="text" name="address">
			<br>
			<input type="button" value="submit" onclick="putCustomer();">
		</form>
	</body>
</html>

页面会使用put方式将form中的信息提交至/firstSteps/spring/customers/{custId}。

在WebRoot/目录下新建delete.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<script type="text/javascript">
			function deleteCustomer(){
				document.getElementById("form").action="/firstSteps/spring/customers/"+document.getElementById("id").value+"?method=delete";
				document.getElementById("form").submit();
			}
		</script>
	</head>

	<body>
		<form action="/firstSteps/spring/customers/0?method=delete" method="post" name="form" id="form">
			id:
			<input type="text" name="id" id="id">
			<br>
			<input type="button" value="submit" onclick="deleteCustomer();">
		</form>
	</body>
</html>

页面会使用delete方式访问/firstSteps/spring/customers/{custId}。

2.测试

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

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

  • postcustomerid:0,Customer[name=0,address=0]

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

  • {0=Customer[name=0,address=0]}

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

  • getcustomerid:0,Customer[name=0,address=0]

说明通过form访问post和get方法成功。

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

  • MethodNotAllowed
  • ThemethodspecifiedintherequestisnotallowedfortheresourceidentifiedbytherequestURI
  • Youcangettechnicaldetailshere.
  • Pleasecontinueyourvisitatourhomepage.

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

说明通过form访问put和delete方法失败。

3.TunnelService和methodParameter

从上面的测试中我们可以看到,不能通过form来直接访问put和delete方法。那要怎么才能方便的从页面上调用Rest呢?幸好Restlet中提供了TunnelService来设置方法参数。

参考org.restlet.Application类中代码:

public TunnelService getTunnelService()
    {
        return (TunnelService)getServices().get(org/restlet/service/TunnelService);
    }

参考org.restlet.service.TunnelService类中代码:

public TunnelService(boolean enabled, boolean methodTunnel, boolean preferencesTunnel, boolean queryTunnel, boolean extensionsTunnel, boolean userAgentTunnel, boolean headersTunnel)
    {
        super(enabled);
        this.extensionsTunnel = extensionsTunnel;
        this.methodTunnel = methodTunnel;
        this.preferencesTunnel = preferencesTunnel;
        this.queryTunnel = queryTunnel;
        this.userAgentTunnel = userAgentTunnel;
        this.headersTunnel = headersTunnel;
        characterSetParameter = "charset";
        encodingParameter = "encoding";
        languageParameter = "language";
        mediaTypeParameter = "media";
        [b][color=red]methodParameter = "method";[/color][/b]
        methodHeader = "X-HTTP-Method-Override";
    }

可以看到TunnelService构造函数中默认的methodParameter属性值为"method"。这样只要使用了Application并且指定提交时的method参数为post/put/delete/get,就可以方便的调用了。

4.使用Application

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

package com.sunny.restlet.order;

import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.routing.Router;

public class CustomerApplication extends Application {

	@Override
	public Restlet createRoot() {
		// TODO Auto-generated method stub
		Router router = new Router(getContext());
		router.attach("/", CustomerResource.class);
		router.attach("/", CustomersResource.class);
		return router;
	}

}

类中将涉及到的资源CustomerResource和CustomersResource都绑定到"/"路径上。

修改src/目录下的applicationContext.xml,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
	xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
	<!-- component -->
	<bean id="component" class="org.restlet.ext.spring.SpringComponent">
		<property name="defaultTarget" ref="application" />
	</bean>
	<!-- application -->
	<bean id="application" class="com.sunny.restlet.order.CustomerApplication">
		<lookup-method name="createRoot" bean="restRouter" />
	</bean>
	<!-- router -->
	<bean id="restRouter" class="org.restlet.ext.spring.SpringBeanRouter">
	</bean>
	<!-- resource -->
	<bean name="/customers" id="customersResrouce"
		class="com.sunny.restlet.order.CustomersResource" />
	<bean name="/customers/{custId}" id="customerResrouce"
		class="com.sunny.restlet.order.CustomerResource" />
	<bean name="/orders/{orderId}/{subOrderId}" id="orderResrouce"
		class="com.sunny.restlet.order.OrderResource" />
	<!-- dao -->
	<bean id="orderDao" class="com.sunny.restlet.order.OrderDaoImpl" />
</beans>

配置中加入了CustomerApplication的配置,行成了Component>Application>Router>Resource的配置链。

5.运行

重新部署程序后,按照第二节测试步骤进行测试。

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

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

  • postcustomerid:0,Customer[name=0,address=0]

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

  • getcustomerid:0,Customer[name=0,address=0]

说明通过form访问post和get方法成功。

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

  • putcustomerid:0,Customer[name=00,address=00]

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

  • {0=Customer[name=00,address=00]}

说明访问put方法成功。

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

  • deletecustomerid:0

刷新getcustomers"链接页面,可以看到customers为空,说明访问delete方法成功。

6.思考

我们可以直接在提交时使用method参数,也可以更改参数名。

在com.sunny.restlet.order.CustomerApplication类中加入构造方法,代码如下:

public CustomerApplication() {
		super();
		getTunnelService().setMethodParameter("_methodName");
		// TODO Auto-generated constructor stub
	}

构造其中将methodParameter设置为"_methodName",这样在页面提交时,将form的action修改为/firstSteps/spring/customers/0?_methodName=put就可以了。

在提交时,如果form的method属性(非action的method参数)不设置或者为get,那不管method参数是什么值,都只能访问到get方法。

如果form的method属性设置为post,那method参数的值只能是post/put/delete(不设置默认为post),否则会报MethodNotAllowed错误。

虽然Spring在不配置CustomerApplication时会自己创建一个默认的Application,但这个默认Application却不支持method参数。而使用CustomerApplication配合method参数可以在页面上方便的调用put和delete,但是Application的配置却写死在了代码中,也算有得有失。要是大家有好的解决方法,请告诉我,谢谢。

相关推荐