基于springmvc实现restful样式的api接口。
[b]1.Restful[/b]
Restful样式的接口将功能抽象为资源resource路径映射,以HTTP GET /resource/{id} 的方式访问。主要分为以下几类接口:
[table]
|[b]地址[/b]|[b]请求方法[/b]|[b]说明[/b]|
|/resources|GET|获取所有资源|
|/resources|POST|创建新资源,content中包含资源内容|
|/resource/{id}|GET|获取编号为id的资源|
|/resource/{id}|PUT|更新编号为id的资源,content中包含资源内容|
|/resource/{id}|DELETE|删除编号为id的资源|
[/table]
{id}称为路径变量,告诉restful你要对哪个资源进行查、改、删。
接口一般返回json/xml格式数据,方便服务端程序、浏览器脚本调用接口并处理返回数据。
按照Restful样式,teacher模块设计为两个资源地址:/restMvc/teachers和/restMvc/teachers/{id}。
基础的spring配置、springmvc配置、各层对象接口实现见前几节内容。
[b]2./teachers[/b]
新建TeachersMvcResource资源类:
类中@Controller和@RequestMapping("/restMvc/teachers")注解声明了此类是Controller类并绑定到/restMvc/teachers地址,两个方法的@RequestMapping(method = { RequestMethod.GET })和@RequestMapping(method = { RequestMethod.POST })注解分别响应GET和POST请求,Contentbody里面的参数会被自动封装成Teacher teacher。
[b]3./teacher/{id}[/b]
新增TeacherMvcResource类:
类中将服务绑定到/restMvc/teacher/{id}地址,方法的@RequestMapping(method = { RequestMethod.GET })、@RequestMapping(method = { RequestMethod.PUT })和@RequestMapping(method = { RequestMethod.DELETE })注解分别响应GET、PUT和POST请求,@PathVariable("id") Integer id接收{id}路径变量。
[b]4.测试[/b]
rest接口可以使用服务端程序(URL、HttpClient库)、js(jquery ajax)进行访问。这里简单实用浏览器插件来测试。
使用FireFox的HttpRquester插件访问接口:
[b]POST[/b]
POST http://localhost:8080/testRest/restMvc/teachers
Content-Type: application/x-www-form-urlencoded
name=a&age=1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:31:56 GMT
{"teacher":{"id":1,"age":1,"name":"a"},"status":"y"}
[b]GET[/b]
GET http://localhost:8080/testRest/restMvc/teachers
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:36:16 GMT
{"teachers":[{"id":1,"age":1,"name":"a"}]}
[b]PUT[/b]
PUT http://localhost:8080/testRest/restMvc/teacher/1
Content-Type: application/x-www-form-urlencoded
name=b&age=2
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:37:41 GMT
{"teacher":{"id":1,"age":2,"name":"b"},"status":"y"}
[b]GET[/b]
GET http://localhost:8080/testRest/restMvc/teacher/1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:38:29 GMT
{"teacher":{"id":1,"age":2,"name":"b"}}
[b]DELETE[/b]
DELETE http://localhost:8080/testRest/restMvc/teacher/1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:38:46 GMT
{"status":"y"}
[b]5.使用服务器程序访问rest[/b]
使用HttpClient库对rest接口进行测试,测试类TestRestMvc代码如下:
输出结果如下:
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[]}
post http://localhost:8080/testRest/restMvc/teachers
{"teacher":{"id":1,"age":1,"name":"a"},"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[{"id":1,"age":1,"name":"a"}]}
get http://localhost:8080/testRest/restMvc/teacher/1
{"teacher":{"id":1,"age":1,"name":"a"}}
put http://localhost:8080/testRest/restMvc/teacher/1
{"teacher":{"id":1,"age":11,"name":"aa"},"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[{"id":1,"age":11,"name":"aa"}]}
delete http://localhost:8080/testRest/restMvc/teacher/1
{"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[]}
[b]1.Restful[/b]
Restful样式的接口将功能抽象为资源resource路径映射,以HTTP GET /resource/{id} 的方式访问。主要分为以下几类接口:
[table]
|[b]地址[/b]|[b]请求方法[/b]|[b]说明[/b]|
|/resources|GET|获取所有资源|
|/resources|POST|创建新资源,content中包含资源内容|
|/resource/{id}|GET|获取编号为id的资源|
|/resource/{id}|PUT|更新编号为id的资源,content中包含资源内容|
|/resource/{id}|DELETE|删除编号为id的资源|
[/table]
{id}称为路径变量,告诉restful你要对哪个资源进行查、改、删。
接口一般返回json/xml格式数据,方便服务端程序、浏览器脚本调用接口并处理返回数据。
按照Restful样式,teacher模块设计为两个资源地址:/restMvc/teachers和/restMvc/teachers/{id}。
基础的spring配置、springmvc配置、各层对象接口实现见前几节内容。
[b]2./teachers[/b]
新建TeachersMvcResource资源类:
package com.sunbin.test.restMvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;
@Controller
@RequestMapping("/restMvc/teachers")
public class TeachersMvcResource {
@Autowired
private TeacherService teacherService;
@RequestMapping(method = { RequestMethod.GET })
public ModelAndView get(HttpServletRequest arg0, HttpServletResponse arg1)
throws Exception {
System.out.println("RestMvc TeachersResource.get");
ModelAndView modelAndView = new ModelAndView(
new MappingJackson2JsonView());
modelAndView.addObject("teachers", teacherService.list());
return modelAndView;
}
@RequestMapping(method = { RequestMethod.POST })
public ModelAndView post(Teacher teacher, HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
ModelAndView modelAndView = new ModelAndView(
new MappingJackson2JsonView());
System.out.println("RestMvc TeachersResource.post:" + teacher);
teacherService.save(teacher);
modelAndView.addObject("status", "y");
return modelAndView;
}
}
类中@Controller和@RequestMapping("/restMvc/teachers")注解声明了此类是Controller类并绑定到/restMvc/teachers地址,两个方法的@RequestMapping(method = { RequestMethod.GET })和@RequestMapping(method = { RequestMethod.POST })注解分别响应GET和POST请求,Contentbody里面的参数会被自动封装成Teacher teacher。
[b]3./teacher/{id}[/b]
新增TeacherMvcResource类:
package com.sunbin.test.restMvc;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;
@Controller
@RequestMapping("/restMvc/teacher/{id}")
public class TeacherMvcResource {
@Autowired
private TeacherService teacherService;
@RequestMapping(method = { RequestMethod.GET })
public ModelAndView get(@PathVariable("id") Integer id,
HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
System.out.println("RestMvc TeacherResource.get:" + id);
ModelAndView modelAndView = new ModelAndView(
new MappingJackson2JsonView());
Teacher teacher = new Teacher();
teacher.setId(id);
modelAndView.addObject("teacher", teacherService.get(teacher));
return modelAndView;
}
@RequestMapping(method = { RequestMethod.PUT })
public ModelAndView put(@PathVariable("id") Integer id, Teacher teacher,
HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
ModelAndView modelAndView = new ModelAndView(
new MappingJackson2JsonView());
// 如果teacher中不含id属性,需要单独设置
// teacher.setId(id);
System.out.println("RestMvc TeacherResource.put:" + id + ":" + teacher);
teacherService.update(teacher);
modelAndView.addObject("status", "y");
return modelAndView;
}
@RequestMapping(method = { RequestMethod.DELETE })
public ModelAndView delete(@PathVariable("id") Integer id,
HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
ModelAndView modelAndView = new ModelAndView(
new MappingJackson2JsonView());
Teacher teacher = new Teacher();
teacher.setId(id);
System.out.println("RestMvc TeacherResource.delete:" + id);
teacherService.remove(teacher);
modelAndView.addObject("status", "y");
return modelAndView;
}
}
类中将服务绑定到/restMvc/teacher/{id}地址,方法的@RequestMapping(method = { RequestMethod.GET })、@RequestMapping(method = { RequestMethod.PUT })和@RequestMapping(method = { RequestMethod.DELETE })注解分别响应GET、PUT和POST请求,@PathVariable("id") Integer id接收{id}路径变量。
[b]4.测试[/b]
rest接口可以使用服务端程序(URL、HttpClient库)、js(jquery ajax)进行访问。这里简单实用浏览器插件来测试。
使用FireFox的HttpRquester插件访问接口:
[b]POST[/b]
POST http://localhost:8080/testRest/restMvc/teachers
Content-Type: application/x-www-form-urlencoded
name=a&age=1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:31:56 GMT
{"teacher":{"id":1,"age":1,"name":"a"},"status":"y"}
[b]GET[/b]
GET http://localhost:8080/testRest/restMvc/teachers
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:36:16 GMT
{"teachers":[{"id":1,"age":1,"name":"a"}]}
[b]PUT[/b]
PUT http://localhost:8080/testRest/restMvc/teacher/1
Content-Type: application/x-www-form-urlencoded
name=b&age=2
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:37:41 GMT
{"teacher":{"id":1,"age":2,"name":"b"},"status":"y"}
[b]GET[/b]
GET http://localhost:8080/testRest/restMvc/teacher/1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:38:29 GMT
{"teacher":{"id":1,"age":2,"name":"b"}}
[b]DELETE[/b]
DELETE http://localhost:8080/testRest/restMvc/teacher/1
-- response --
200 OK
Server: Apache-Coyote/1.1
Pragma: no-cache
Cache-Control: no-cache, no-store, max-age=0
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/json;charset=UTF-8
Content-Language: zh-CN
Transfer-Encoding: chunked
Date: Tue, 23 May 2017 02:38:46 GMT
{"status":"y"}
[b]5.使用服务器程序访问rest[/b]
使用HttpClient库对rest接口进行测试,测试类TestRestMvc代码如下:
package com.sunbin.test.restMvc;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class TestRestMvc {
public static final String URL_BASE = "http://localhost:8080/testRest/restMvc/";
public static void main(String[] args) throws ParseException,
ClientProtocolException, IOException {
String module = "teacher";
String url = "";
DefaultHttpClient client = new DefaultHttpClient();
HttpEntity entity = null;
String result = "";
Map map = null;
HttpGet httpGet = null;
HttpPost httpPost = null;
HttpPut httpPut = null;
HttpDelete httpDelete = null;
url = URL_BASE + module + "s";
System.out.println("get\t " + url);
httpGet = new HttpGet(url);
result = EntityUtils.toString(client.execute(httpGet).getEntity());
System.out.println(result);
url = URL_BASE + module + "s";
System.out.println("post\t " + url);
httpPost = new HttpPost(url);
map = new HashMap();
map.put("name", "a");
map.put("age", "1");
entity = new UrlEncodedFormEntity(getParam(map), "UTF-8");
httpPost.setEntity(entity);
result = EntityUtils.toString(client.execute(httpPost).getEntity());
System.out.println(result);
url = URL_BASE + module + "s";
System.out.println("get\t " + url);
httpGet = new HttpGet(url);
result = EntityUtils.toString(client.execute(httpGet).getEntity());
System.out.println(result);
url = URL_BASE + module + "/1";
System.out.println("get\t " + url);
httpGet = new HttpGet(url);
result = EntityUtils.toString(client.execute(httpGet).getEntity());
System.out.println(result);
url = URL_BASE + module + "/1";
System.out.println("put\t " + url);
httpPut = new HttpPut(url);
map = new HashMap();
map.put("name", "aa");
map.put("age", "11");
entity = new UrlEncodedFormEntity(getParam(map), "UTF-8");
httpPut.setEntity(entity);
result = EntityUtils.toString(client.execute(httpPut).getEntity());
System.out.println(result);
url = URL_BASE + module + "s";
System.out.println("get\t " + url);
httpGet = new HttpGet(url);
result = EntityUtils.toString(client.execute(httpGet).getEntity());
System.out.println(result);
url = URL_BASE + module + "/1";
System.out.println("delete\t " + url);
httpDelete = new HttpDelete(url);
result = EntityUtils.toString(client.execute(httpDelete).getEntity());
System.out.println(result);
url = URL_BASE + module + "s";
System.out.println("get\t " + url);
httpGet = new HttpGet(url);
result = EntityUtils.toString(client.execute(httpGet).getEntity());
System.out.println(result);
}
public static List<NameValuePair> getParam(Map parameterMap) {
List<NameValuePair> param = new ArrayList<NameValuePair>();
Iterator it = parameterMap.entrySet().iterator();
while (it.hasNext()) {
Entry parmEntry = (Entry) it.next();
param.add(new BasicNameValuePair((String) parmEntry.getKey(),
(String) parmEntry.getValue()));
}
return param;
}
}
输出结果如下:
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[]}
post http://localhost:8080/testRest/restMvc/teachers
{"teacher":{"id":1,"age":1,"name":"a"},"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[{"id":1,"age":1,"name":"a"}]}
get http://localhost:8080/testRest/restMvc/teacher/1
{"teacher":{"id":1,"age":1,"name":"a"}}
put http://localhost:8080/testRest/restMvc/teacher/1
{"teacher":{"id":1,"age":11,"name":"aa"},"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[{"id":1,"age":11,"name":"aa"}]}
delete http://localhost:8080/testRest/restMvc/teacher/1
{"status":"y"}
get http://localhost:8080/testRest/restMvc/teachers
{"teachers":[]}