Rest之路 -- 从第二个Rest application里面分析 Rest 方法
引言
在此之前,我们实现了第一个Rest application,通过分析她,我们了解了 Rest 程序的基本要素;这里,我们将会对第一个 Rest application 的功能进行扩充(实现 CRUD)。为了简化流程,我们依然采用文件的方式来模拟数据库操作。
第二个 Rest application
User
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | import java.io.Serializable; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement (name = "user" ) public class User implements Serializable { private int id; private String name; private String profession; public User(){} public User( int id, String name, String profession){ this .id = id; this .name = name; this .profession = profession; } public int getId() { return id; } @XmlElement public void setId( int id) { this .id = id; } public String getName() { return name; } @XmlElement public void setName(String name) { this .name = name; } public String getProfession() { return profession; } @XmlElement public void setProfession(String profession) { this .profession = profession; } @Override public boolean equals(Object object){ if (object == null ){ return false ; } else if (!(object instanceof User)){ return false ; } else { User user = (User)object; if (id == user.getId() && name.equals(user.getName()) && profession.equals(user.getProfession()) ){ return true ; } } return false ; } } |
Userdao
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public class UserDao { public List<User> getAllUsers(){ List<User> userList = null ; try { File file = new File( "Users.dat" ); if (!file.exists()) { User user = new User( 1 , "Mahesh" , "Teacher" ); userList = new ArrayList<User>(); userList.add(user); saveUserList(userList); } else { FileInputStream fis = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(fis); userList = (List<User>) ois.readObject(); ois.close(); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return userList; } public User getUser( int id){ List<User> users = getAllUsers(); for (User user: users){ if (user.getId() == id){ return user; } } return null ; } public int addUser(User pUser){ List<User> userList = getAllUsers(); boolean userExists = false ; for (User user: userList){ if (user.getId() == pUser.getId()){ userExists = true ; break ; } } if (!userExists){ userList.add(pUser); saveUserList(userList); return 1 ; } return 0 ; } public int updateUser(User pUser){ List<User> userList = getAllUsers(); for (User user: userList){ if (user.getId() == pUser.getId()){ int index = userList.indexOf(user); userList.set(index, pUser); saveUserList(userList); return 1 ; } } return 0 ; } public int deleteUser( int id){ List<User> userList = getAllUsers(); for (User user: userList){ if (user.getId() == id){ int index = userList.indexOf(user); userList.remove(index); saveUserList(userList); return 1 ; } } return 0 ; } private void saveUserList(List<User> userList){ try { File file = new File( "Users.dat" ); FileOutputStream fos; fos = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(userList); oos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } |
UserService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import java.io.IOException; import java.util.List; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.OPTIONS; import javax.ws.rs.POST; 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.Context; import javax.ws.rs.core.MediaType; @Path ( "/UserService" ) public class UserService { UserDao userDao = new UserDao(); private static final String SUCCESS_RESULT= "<result>success</result>" ; private static final String FAILURE_RESULT= "<result>failure</result>" ; @GET @Path ( "/users" ) @Produces (MediaType.APPLICATION_XML) public List<User> getUsers(){ return userDao.getAllUsers(); } @GET @Path ( "/users/{userid}" ) @Produces (MediaType.APPLICATION_XML) public User getUser( @PathParam ( "userid" ) int userid){ return userDao.getUser(userid); } @PUT @Path ( "/users" ) @Produces (MediaType.APPLICATION_XML) @Consumes (MediaType.APPLICATION_FORM_URLENCODED) public String createUser( @FormParam ( "id" ) int id, @FormParam ( "name" ) String name, @FormParam ( "profession" ) String profession, @Context HttpServletResponse servletResponse) throws IOException{ User user = new User(id, name, profession); int result = userDao.addUser(user); if (result == 1 ){ return SUCCESS_RESULT; } return FAILURE_RESULT; } @POST @Path ( "/users" ) @Produces (MediaType.APPLICATION_XML) @Consumes (MediaType.APPLICATION_FORM_URLENCODED) public String updateUser( @FormParam ( "id" ) int id, @FormParam ( "name" ) String name, @FormParam ( "profession" ) String profession, @Context HttpServletResponse servletResponse) throws IOException{ User user = new User(id, name, profession); int result = userDao.updateUser(user); if (result == 1 ){ return SUCCESS_RESULT; } return FAILURE_RESULT; } @DELETE @Path ( "/users/{userid}" ) @Produces (MediaType.APPLICATION_XML) public String deleteUser( @PathParam ( "userid" ) int userid){ int result = userDao.deleteUser(userid); if (result == 1 ){ return SUCCESS_RESULT; } return FAILURE_RESULT; } @OPTIONS @Path ( "/users" ) @Produces (MediaType.APPLICATION_XML) public String getSupportedOperations(){ return "<operations>GET, PUT, POST, DELETE</operations>" ; } } |
WebServiceTester(Write test client ourselves)
Jersey允许我们自己实现测试类(Web Service Client)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | import java.util.List; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Form; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.MediaType; public class WebServiceTester { private Client client; private String REST_SERVICE_URL = "http://localhost:8080/UserManagement/rest/UserService/users" ; private static final String SUCCESS_RESULT= "<result>success</result>" ; private static final String PASS = "pass" ; private static final String FAIL = "fail" ; private void init(){ this .client = ClientBuilder.newClient(); } public static void main(String[] args){ WebServiceTester tester = new WebServiceTester(); //initialize the tester tester.init(); //test get all users Web Service Method tester.testGetAllUsers(); //test get user Web Service Method tester.testGetUser(); //test update user Web Service Method tester.testUpdateUser(); //test add user Web Service Method tester.testAddUser(); //test delete user Web Service Method tester.testDeleteUser(); } //Test: Get list of all users //Test: Check if list is not empty private void testGetAllUsers(){ GenericType<List<User>> list = new GenericType<List<User>>() {}; List<User> users = client .target(REST_SERVICE_URL) .request(MediaType.APPLICATION_XML) .get(list); String result = PASS; if (users.isEmpty()){ result = FAIL; } System.out.println( "Test case name: testGetAllUsers, Result: " + result ); } //Test: Get User of id 1 //Test: Check if user is same as sample user private void testGetUser(){ User sampleUser = new User(); sampleUser.setId( 1 ); User user = client .target(REST_SERVICE_URL) .path( "/{userid}" ) .resolveTemplate( "userid" , 1 ) .request(MediaType.APPLICATION_XML) .get(User. class ); String result = FAIL; if (sampleUser != null && sampleUser.getId() == user.getId()){ result = PASS; } System.out.println( "Test case name: testGetUser, Result: " + result ); } //Test: Update User of id 1 //Test: Check if result is success XML. private void testUpdateUser(){ Form form = new Form(); form.param( "id" , "1" ); form.param( "name" , "suresh" ); form.param( "profession" , "clerk" ); String callResult = client .target(REST_SERVICE_URL) .request(MediaType.APPLICATION_XML) .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), String. class ); String result = PASS; if (!SUCCESS_RESULT.equals(callResult)){ result = FAIL; } System.out.println( "Test case name: testUpdateUser, Result: " + result ); } //Test: Add User of id 2 //Test: Check if result is success XML. private void testAddUser(){ Form form = new Form(); form.param( "id" , "2" ); form.param( "name" , "naresh" ); form.param( "profession" , "clerk" ); String callResult = client .target(REST_SERVICE_URL) .request(MediaType.APPLICATION_XML) .put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), String. class ); String result = PASS; if (!SUCCESS_RESULT.equals(callResult)){ result = FAIL; } System.out.println( "Test case name: testAddUser, Result: " + result ); } //Test: Delete User of id 2 //Test: Check if result is success XML. private void testDeleteUser(){ String callResult = client .target(REST_SERVICE_URL) .path( "/{userid}" ) .resolveTemplate( "userid" , 2 ) .request(MediaType.APPLICATION_XML) .delete(String. class ); String result = PASS; if (!SUCCESS_RESULT.equals(callResult)){ result = FAIL; } System.out.println( "Test case name: testDeleteUser, Result: " + result ); } } |
在Eclipse里面,选中 WebServiceTester, 右键 -> run as Java application, 我们会在 console 里面看到一下输出
1 2 3 4 5 | Test case name: testGetAllUsers, Result: pass Test case name: testGetUser, Result: pass Test case name: testUpdateUser, Result: pass Test case name: testAddUser, Result: pass Test case name: testDeleteUser, Result: pass |
Rest verbs
现在,我们再来分析一下 Rest verbs, 通过一下的表格我们能够更好地理解他们...
S.N. | HTTP Method, URI and Operation |
---|---|
1 | GET http://localhost:8080/UserManagement/rest/UserService/users 获取 users 列表 (只读的) |
2 | GET http://localhost:8080/UserManagement/rest/UserService/users/1 获取 id=1 的user (只读的) |
3 | PUT http://localhost:8080/UserManagement/rest/UserService/users/2 插入 id =2 的 user (幂等的) |
4 | POST http://localhost:8080/UserManagement/rest/UserService/users/2 更新 id=2 的 user (N/A) |
5 | DELETE http://localhost:8080/UserManagement/rest/UserService/users/1 删除 id=1 的 user (幂等的) |
6 | OPTIONS http://localhost:8080/UserManagement/rest/UserService/users 列出 service 上面的所有 operations (Read Only) |
7 | HEAD http://localhost:8080/UserManagement/rest/UserService/users 返回 HTTP HEAD (Read Only) |
注: 从URI 中, 我们不容易看出来究竟要执行 Rest service 的那个operation,operation需要体现以Class.Method的形式体现出来。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现