REST(二)Jersey实现REST

阅读更多
Jersey是JAX-RS(JSR311)开源参考实现,用于构建RESTful Web service。它包含三个部分:
核心服务器(Core Server) 通过提供JSR 311中标准化的注释和API标准化,可以用直观的方式开发RESTful Web服务。
核心客户端(Core Client) Jersey客户端API能够帮助开发者与RESTful服务轻松通信;
集成(Integration) Jersey还提供可以轻松继承Spring、Guice、Apache Abdera的库。

本节使用Jersey集成Spring搭建。

1.spring web基础环境
eclipse的Maven Web工程,工程名为testRest。集成spring并创建简单的Teacher模块,包含POJO、SERVICE、DAO层简单代码,使用spring注解注入bean。
见 spring mvc系列,第六篇使用springmvc实现了REST。
后续各框架陆续并入该工程。

2.REST地址
设计jersey模块rest接口地址:
/jersey/teachers GET 获取所有资源
/jersey/teachers POST 创建新资源,content中包含资源内容
/jersey/teacher/{id} GET 获取编号为id的资源
/jersey/teacher/{id} PUT 更新编号为id的资源,content中包含资源内容
/jersey/teacher/{id} DELETE 删除编号为id的资源

3.jersey库
在项目pom.xml中加入Jersey依赖:

	2.25.1

	
	...
	
	
		org.glassfish.jersey.containers
		
		jersey-container-servlet
		${jersey.version}
	
	
	
		org.glassfish.jersey.core
		jersey-client
		${jersey.version}
	
	
		org.glassfish.jersey.ext
		jersey-spring3
		${jersey.version}
		
			
				org.springframework
				spring
			
			
				org.springframework
				spring-core
			
			
				org.springframework
				spring-web
			
			
				org.springframework
				spring-beans
			
			
				org.springframework
				spring-context
			
		
	
	
		org.codehaus.jackson
		jackson-jaxrs
		1.8.11
	
		
	...

使用Jersey老版本2.25.1,与spring4集成也可使用jersey-spring3包。不使用jersey-client调用api可不载入该依赖。

4.Servlet
配置Jersey访问入口。


	Jersey REST Service
	org.glassfish.jersey.servlet.ServletContainer
	
		javax.ws.rs.Application
		com.sunbin.test.jersey.JerseyConfig
	
	1


	Jersey REST Service
	/jersey/*


Jersey Servlet将拦截/jersey/*下的所有访问。
因为Jersey服务必须通过容器来访问,实践过程中发现直接在web.xml中配置:

jersey.config.server.provider.packages
com.sunbin.test.jersey

不生效,还是需要实现Application来设置扫描的包路径。
新增JerseyConfig类:
package com.sunbin.test.jersey;

import org.glassfish.jersey.server.ResourceConfig;

import org.codehaus.jackson.jaxrs.JacksonJsonProvider;

// TODO: Auto-generated Javadoc
/**
 * The Class JerseyConfig.
 */
public class JerseyConfig extends ResourceConfig {

	/**
	 * Instantiates a new jersey config.
	 */
	public JerseyConfig() {
		// 配置扫描包
		packages("com.sunbin.test.jersey");
		// 配置json转换。配置后如果api定义返回类型为json、且pojo注解XmlRootElement,将自动转为json返回;否则需要自己转换
		register(JacksonJsonProvider.class);
	}
}

Jersey将com.sunbin.test.jersey包下的类中的注解,转换为REST服务。

5.实现api
在com.sunbin.test.jersey新增TeachersResource类,以实现/teachers路径的接口:
package com.sunbin.test.jersey;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.springframework.beans.factory.annotation.Autowired;

import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

@Path("teachers")
@Produces(MediaType.APPLICATION_JSON)
public class TeachersResource {

	@Autowired
	private TeacherService teacherService;

	@GET
	public Map get() {
		System.out.println("Jersey TeachersResource.get");
		Map map = new HashMap();
		map.put("teachers", teacherService.list());
		return map;
	}

	@POST
	public Map post(@FormParam("age") int age, @FormParam("name") String name) {
		Map map = new HashMap();
		try {
			Teacher teacher = new Teacher();
			teacher.setName(name);
			teacher.setAge(age);
			System.out.println("Jersey TeachersResource.post:" + teacher);
			teacherService.save(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}
}

用到了以下JAX-RS注解:
@Path("teachers")绑定路径:/servlet路径/teachers。可在类和方法上加注解。
@Produces(MediaType.APPLICATION_JSON)支持返回类型:application/json。可支持多种类型,按请求header:AcceptType返回。
@GET:GET请求的响应方法。
@POST:POST请求的响应方法。
@FormParam("age") int age, @FormParam("name") String name:获取通过application/x-www-form-urlencoded方式提交的参数。

新增TeacherResource类,以实现/teacher/{id}路径的接口:
package com.sunbin.test.jersey;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.springframework.beans.factory.annotation.Autowired;

import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

@Path("teacher/{id}")
@Produces(MediaType.APPLICATION_JSON)
public class TeacherResource {

	@Autowired
	private TeacherService teacherService;

	@GET
	public Map get(@PathParam("id") int id) {
		System.out.println("Jersey TeacherResource.get:" + id);
		Teacher teacher = new Teacher();
		teacher.setId(id);
		Map map = new HashMap();
		map.put("teacher", teacherService.get(teacher));
		return map;
	}

	@PUT
	public Map put(@PathParam("id") int id, @FormParam("age") int age,
			@FormParam("name") String name) {
		Map map = new HashMap();
		try {
			Teacher teacher = new Teacher();
			teacher.setId(id);
			teacher.setName(name);
			teacher.setAge(age);
			System.out.println("Jersey TeacherResource.put:" + id + ":"
					+ teacher);
			teacherService.update(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

	@DELETE
	public Map delete(@PathParam("id") int id) {
		Map map = new HashMap();
		try {
			System.out.println("Jersey TeacherResource.delete:" + id);
			Teacher teacher = new Teacher();
			teacher.setId(id);
			teacherService.remove(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}
}

用到了以下JAX-RS注解:
@PathParam("id"):获取路径参数{id}
@PUT:PUT请求的响应方法。
@DELETE:DELETE请求的响应方法。

6.js测试
Jersey不像springmvc一样,可以通过在POST form中增加_method=PUT/DELETE隐藏参数的方法来支持表单直接提交PUT/DELETE,所以要通过javascript或者程序来访问。
先使用jquery库来进行ajax访问测试。
在src\main\webapp\rest目录下新建index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>



	
	teacher
	
	


	save
	
name: age:

list
id name age 操作
${teacher.id} [url=javascript:void(0);]get[/url] [url=javascript:void(0);]remove[/url]

重新部署后,使用浏览器访问 http://localhost:8080/testRest/rest,可以看到页面:
REST(二)Jersey实现REST_第1张图片
通过js访问REST api,就类似网站使用第三方登录(QQ、微博等)后访问用户头像昵称的过程,当然登录时一般使用OAUTH2.0 做认证方案。

7.JerseyClient测试
Jersey提供Client库用于测试JAX-RS接口。Client不仅可用来测Jersey REST,也可以用来测试其他框架实现的接口和http服务。
新建TestJersey类,代码如下:
package com.sunbin.test.jersey;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Form;

public class TestJersey {

	public static final String URL_BASE = "http://localhost:8080/testRest/jersey/";

	public static void main(String[] args) {
		Client client = ClientBuilder.newClient();
		String module = "teacher";
		String url = "";
		String result = "";
		Entity
entity = null; Form form = null; WebTarget baseTarget = client.target(URL_BASE); WebTarget target = null; url = URL_BASE + module + "s"; System.out.println("get\t" + url); target = baseTarget.path(module + "s"); result = target.request().get(String.class); System.out.println(result); url = URL_BASE + module + "s"; System.out.println("post\t " + url); target = baseTarget.path(module + "s"); form = new Form().param("age", "1").param("name", "a"); entity = Entity.form(form); result = target.request().post(entity, String.class); System.out.println(result); url = URL_BASE + module + "s"; System.out.println("get\t" + url); target = baseTarget.path(module + "s"); result = target.request().get(String.class); System.out.println(result); url = URL_BASE + module + "/1"; System.out.println("get\t " + url); target = baseTarget.path(module + "/1"); result = target.request().get(String.class); System.out.println(result); url = URL_BASE + module + "/1"; System.out.println("put\t " + url); target = baseTarget.path(module + "/1"); form = new Form().param("age", "11").param("name", "aa"); entity = Entity.form(form); result = target.request().put(entity, String.class); System.out.println(result); url = URL_BASE + module + "s"; System.out.println("get\t" + url); target = baseTarget.path(module + "s"); result = target.request().get(String.class); System.out.println(result); url = URL_BASE + module + "/1"; System.out.println("delete\t " + url); target = baseTarget.path(module + "/1"); result = target.request().delete(String.class); System.out.println(result); url = URL_BASE + module + "s"; System.out.println("get\t" + url); target = baseTarget.path(module + "s"); result = target.request().get(String.class); System.out.println(result); } }

测试结果如下:
get	http://localhost:8080/testRest/jersey/teachers
{"teachers":[]}
post	 http://localhost:8080/testRest/jersey/teachers
{"status":"y"}
get	http://localhost:8080/testRest/jersey/teachers
{"teachers":[{"id":1,"age":1,"name":"a"}]}
get	 http://localhost:8080/testRest/jersey/teacher/1
{"teacher":{"id":1,"age":1,"name":"a"}}
put	 http://localhost:8080/testRest/jersey/teacher/1
{"status":"y"}
get	http://localhost:8080/testRest/jersey/teachers
{"teachers":[{"id":1,"age":11,"name":"aa"}]}
delete	 http://localhost:8080/testRest/jersey/teacher/1
{"status":"y"}
get	http://localhost:8080/testRest/jersey/teachers
{"teachers":[]}

通过js访问REST api,类似于服务端、桌面应用、移动端APP使用第三方登录(QQ、微信等)后访问用户数据并保存的过程。
  • REST(二)Jersey实现REST_第2张图片
  • 大小: 24.6 KB
  • 查看图片附件

你可能感兴趣的:(rest,jersey,spring)