欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

REST(五)CXF实现REST

程序员文章站 2022-04-04 12:30:28
...
Apache CXF以前一般用来开发基于SOAP协议的Web Service,其实CXF也实现了JAX-RS(JSR311)接口,这里我们用它实现REST API。

1.spring web基础环境
见之前章节创建的web工程testRest。

2.REST地址
与上一节类似,设计RESTEasy模块/restCxf/*。

3.RESTEasy库
在项目pom.xml中加入RESTEasy依赖:
<properties>
	<restCxf.version>3.1.0</restCxf.version>
</properties>
<dependencies>	
	...
	<!-- restCxf begin -->
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-frontend-jaxws</artifactId>
		<version>${restCxf.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-transports-http</artifactId>
		<version>${restCxf.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-transports-http-jetty</artifactId>
		<version>${restCxf.version}</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-frontend-jaxrs</artifactId>
		<version>${restCxf.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.apache.cxf</groupId>
	    <artifactId>cxf-rt-rs-client</artifactId>
	    <version>${restCxf.version}</version>
	</dependency>
	<!-- restCxf end -->
	...

加入cxf jaxrs库、http库和client库。

4.Servlet
配置RESTEasy访问入口。
<!-- restCxf -->
<servlet>
	<servlet-name>restCxf</servlet-name>
	<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>restCxf</servlet-name>
	<url-pattern>/restCxf/*</url-pattern>
</servlet-mapping>

restCxfServlet将拦截/restCxf/*下的所有访问。

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

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

import javax.servlet.http.HttpServletRequest;
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.Context;
import javax.ws.rs.core.MediaType;

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

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

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

	@Autowired
	private TeacherService teacherService;
	
	@GET
    public Map get(@Context HttpServletRequest arg0) {
		System.out.println("RestCxf TeachersResource.get:"
				+ arg0.getSession().getId());
		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("RestCxf TeachersResource.post:"+teacher);
			teacherService.save(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}
}

路径注解@Path、返回类型注解@Produces、访问方法@GET、参数读取@FormParam,都和Jersey的JAX-RS相同。

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

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 org.springframework.stereotype.Component;

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

@Component
@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("RestCxf 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("RestCxf 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("RestCxf 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;
	}
}


6.js测试
使用上一节的测试页面src\main\webapp\rest\index.jsp进行测试:
...
	<script type="text/javascript">
		// 测试框架
		//var restType = "jersey";
		//var restType = "restlet";
		//var restType = "resteasy";
		var restType = "restCxf";
		//var restType = "restMvc";
...

重新部署后,使用浏览器访问http://localhost:8080/testRest/rest,测试内容和Restlet测试相同。

7.CXF Client测试
CXF提供rest Client库用于测试REST接口。
新建TestRestCxf类,代码如下:
package com.sunbin.test.restCxf;

import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import org.apache.cxf.jaxrs.client.WebClient;

public class TestRestCxf {

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

	public static void main(String[] args) {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "config/restCxf/restCxfClient.xml" });
		WebClient teachersClient = (WebClient) context
				.getBean("teachersClient");
		WebClient teacherClient = ((WebClient) context.getBean("teacherClient"))
				.path("{id}", "1");

		String module = "teacher";
		String url = "";
		String result = "";
		Entity<Form> entity = null;
		Form form = null;

		url = URL_BASE + module + "s";
		System.out.println("get\t" + url);
		result = teachersClient.get(String.class);
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("post\t " + url);
		form = new Form().param("age", "1").param("name", "a");
		entity = Entity.form(form);
		result = teachersClient.post(entity, String.class);
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t" + url);
		result = teachersClient.get(String.class);
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("get\t " + url);
		result = teacherClient.get(String.class);
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("put\t " + url);
		form = new Form().param("age", "11").param("name", "aa");
		entity = Entity.form(form);
		result = teacherClient.put(entity, String.class);
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t" + url);
		result = teachersClient.get(String.class);
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("delete\t " + url);
		result = teacherClient.delete().readEntity(String.class);
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t" + url);
		result = teachersClient.get(String.class);
		System.out.println(result);
	}
}

测试结果与Restlet类似。
相关标签: rest spring cxf