让Servlet支持REST风格的url

前言

Servlet自从上了3.0版本之后,用起来已经是相当舒服了。注解的加入,让你基本可以抛弃web.xml,零配置写web。

不过,用了之后,还是有些遗憾。就是REST风格URL的支持。很久之前用过SpringMVC之后,对于REST风格的URL就喜欢得不得了。上网查了下,发现了个项目servletrest,项目托管在google code上:http://code.google.com/p/servletrest/

源码就几个类,很快就看完了,也试用了一下。确实是可以支持,但是bug也比较明显。最明显的一个就是,支持了REST的servlet,是无法获取到ServletContext。原因是servletrest在初始化servlet的时候,没有调用servlet的init方法,即没有初始化ServletConfig。还有一个问题,就是获取URI中的参数时,太过繁琐。而且基于第一个问题,参数其实是获取不到的。

花了点时间,重新写了个新的实现,叫summer-restful。主要作用,就是让普通的servlet支持rest风格的url,并且也修复中servletrest的明显bug。

实现原理

定义一个Filter。

init

在容器启动的时候,对所有已通过注解标记的servlet进行扫描验证。这里提到的注解是我们自定义的,叫@SummerServlet,参数有两个,name,UrlPatterns。符合规则的servlet初始化,并用他们的urlPatterns作为该servlet的key,存入一个Map中进行维护。说明下,我们自定义的@SummerServlet中的urlPatterns,跟原生servlet的UrlPatterns有些区别。自定义的urlPatterns中,是支持类似这种格式的url:/*/detail/* 的,也通过这里,让普通的servlet支持了REST风格的url。

doFilter

过滤器拦截所有请求。分析请求的servletPath,跟Map中的key进行比对,若匹配,则返回key对应的servlet,并且会注入url中的参数到request;否则,执行默认的动作。

使用

有两个步骤。

配置全局的Filter

通过web.xml配置的话,例子如下

<filter>
	<filter-name>summerFilter</filter-name>
	<filter-class>cn._5iurl.restful.SummerFilter</filter-class>
	<init-param>
		<param-name>servletPackage</param-name>
		<param-value>cn._5iurl.test.servlet</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>summerFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

也可以通过注解来配置。这时候需要新建一个Filter继承SummerFilter,例子如下

@WebFilter(filterName="restFilter", [email protected](name="servletPackage", value="cn._5iurl.test.servlet"), urlPatterns="/*")
public class CRestFilter extends SummerFilter{

}

配置Servlet

在需要Rest风格URL的servlet类中,不再配置到xml或者用@WebServlet注解,而是改用@SummerServlet注解。例子如下

@SummerServlet(name="detailServlet", urlPatterns="/*/detail/*")
public class DetailServlet extends HttpServlet{

	private static final long serialVersionUID = 8268477143225755822L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String category = (String)req.getAttribute("p0");
		String id = (String)req.getAttribute("p1");

		req.setAttribute("id", id);
		req.getRequestDispatcher("/WEB-INF/www/"+category+"/detail.jsp").forward(req, resp);
	}

}

获取URL中的参数

获取url中的参数。啥意思呢?还是上面的例子。假设用户访问的是:http://localhost:8015/cms/user/detail/1,可以看到,是符合我们定义的url规则:

/*/detail/*

那我们怎么获取中隐藏其中的参数值:user和1呢。还是看例子

String category = (String)req.getAttribute("p0");
String id = (String)req.getAttribute("p1");

源码

源码已经放在[email protected]上面,有兴趣可以看下:http://git.oschina.net/cevin15/summer-restful

时间: 2024-08-25 03:00:27

让Servlet支持REST风格的url的相关文章

springMVC的rest风格的url请求

rest是一个架构风格,用url来访问网络上的任何资源.rest的一种思想就是用http中的动作get,post,put,delete,来进行增删改查. 这里介绍的是springMVC的rest请求. 不包含webservice的JAX-RS的例子.rest风格的webservice可以用cxf框架进行实现.也很简单. 1 首先准备web项目需要的jar包,也就是springMVC所依赖的jar: 2 创建一个动态的web工程:这里首先需要配置web.xml文件注册springMVC的前端控制器

HiddenHttpMethodFilter进行请求过滤,实现Rest风格的url

Rest 风格的 URL. 以 CRUD 为例: 新增: /order POST 修改: /order/1 PUT update?id=1 获取:/order/1 GET get?id=1 删除: /order/1 DELETE delete?id=1. 浏览器只支持Post和get的方式,想要实现delete和put的方式,需要使用过滤器HiddenHttpMethodFilter 1,配置过滤器 <filter> <filter-name>hidden</filter-n

当当网开源Dubbox,扩展Dubbo服务框架支持REST风格远程调用

当当网近日开源了Dubbox项目,可为Dubbo服务框架提供多项扩展功能,包括REST风格远程调用.Kryo/FST序列化等等. 当当网架构部和技术委员会架构师沈理向InfoQ中文站介绍了Dubbox项目,开发背景和主要特点描述如下: Dubbo是一个被国内很多互联网公司广泛使用的开源分布式服务框架,即使从国际视野来看应该也是一个非常全面的SOA基础框架.作为一个重要的技术研究课题,在当当网我们根据自身的需求,为Dubbo实现了一些新的功能,并将其命名为Dubbox(即Dubbo eXtensi

Spring MVC 支持 RESTful 风格编程

1.配置 web.xml <!-- 配置 SpringMVC DispatcherServlet --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置 DispatcherServlet 的一个初始化

Spring MVC 使用HiddenHttpMethodFilter配置Rest风格的URL

/** Rest 风格的 URL. 以 CRUD 为例: 新增: /order POST 修改: /order/1 PUT update?id=1 获取:/order/1 GET get?id=1 删除: /order/1 DELETE delete?id=1 如何发送 PUT 请求和 DELETE 请求呢 ? 1. 需要在web.xml文件中配置 HiddenHttpMethodFilter <!-- 配置 org.springframework.web.filter.HiddenHttpMe

【Python】Django 支持 restful 风格 url

URL通配符示例: url(r'^file_download/(?P<filename>(.)*)$', views.FILE_DOWNLOAD_VIEW.as_view()), 代码示例: def get(self, request, filename): from common.s3_storage import S3_STORAGE s3_storage = S3_STORAGE() key = s3_storage.package_bucket.get_key(filename) as

Nginx笔记:支持对用户提交URL和服务的URL不一致时,保持对POST提交的支持

用户访问的URL和服务的URL不一致,需要对URL修改,同时使用的是POST提交方式 location ~* ^/portalproxy/([0-9]*)/portal$ { #rewrite '^/portalproxy/([0-9]*)/portal$' http://$host/portalproxy/portal?url_timetemp=$1 break; proxy_pass http://portalproxy/portalproxy/portal?url_timetemp=$1&

3、REST风格的URL

1.概述 HTTP协议里面,四个表示操作方式的动词:GET.POST.PUT.DELETE,它们分别对应四种基本的操作,GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源.        示例:    —— /order/1        HTTP GET:得到id=1的order    —— /order/1     HTTP DELETE:删除id=1的order    —— /order/1     HTTP PUT:更新id=1的order    ——

Servlet支持上传多张图片

首先前端的表单是这个形式: <form  target="_self" method="post" action="fileUploadMultyServlet" enctype="multipart/form-data" > <label>上传材料<input type="file" id="image" name='image'></labe