Struts2提供了一個restful的插件:struts2-rest-plugin-2.3.16.1.jar
這個插件可以把Struts2當做restful來使用,不過它的rest功能目前來說有點“死板”,定死了格式,這是使用這個插件不是那么爽的地方,或許有別的方式可以修改,之后再研究。
這是它的rest格式:
RestActionMapper 對 HTTP 請求的處理
HTTP 方法 | URI | 調用 Action 的方法 | 請求參數 |
GET | /user | index | |
POST | /user | create | |
PUT | /user/2 | update | id=2 |
DELETE | /user/2 | destroy | id=2 |
GET | /user/2 | show | id=2 |
GET | /user/2/edit | edit | id=2 |
GET | /user/new | editNew |
直接上自己學習寫的例子:
在eclipse中怎么加插件就不寫了,引包就可以了,記得要把Convertion的包也引入。
1)web.xml的配置:
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2)新增一個Entity:
package com.my.beans; import java.util.Date; public class User { private int Id; private String username; private String password; private int age; private Date createTime; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public int getId() { return Id; } public void setId(int id) { Id = id; } public User(int id, String username, String password, int age, Date createTime) { Id = id; this.username = username; this.password = password; this.age = age; this.createTime = createTime; } public User() { } }
3) 建一個Service類,用於模擬持久層的讀寫用:
package com.my.service; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import com.my.beans.User; public class UserService { // new一個用戶列表數據對象,模擬持久層數據 private static Map<Integer, User> users = new HashMap<Integer, User>(); // 初始化用戶列表數據,模擬持久層數據 static { users.put(1, new User(1, "robin1", "password1", 18, new Date())); users.put(2, new User(2, "robin2", "password2", 19, new Date())); users.put(3, new User(3, "robin3", "password3", 20, new Date())); users.put(4, new User(4, "robin4", "password4", 21, new Date())); users.put(5, new User(5, "robin5", "password5", 22, new Date())); } /** * 通過用戶ID取得用戶實體 * @param id * @return */ public User getId(int id) { return users.get(id); } /** * 取得所有用戶列表 * @return */ public List<User> getAll() { return new ArrayList<User>(users.values()); } /** * 更新用戶 * @param user */ public void update(User user) { if (user.getId() > 0) { users.put(user.getId(), user); } } /** * 新增用戶 * @param user */ public void add(User user) { int size = users.size(); int id = size + 1; user.setId(id); users.put(id, user); } /** * 刪除用戶 * @param id */ public void remove(int id) { users.remove(id); } }
4) 新建一個struts.xml在src目錄下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 把它設置為開發模式,發布時要設置為false --> <constant name="struts.devMode" value="true" /> <!-- 設置在class被修改時是否熱加載,發布時要設置為false --> <constant name="struts.convention.classes.reload" value="true"/> <!-- 自動動態方法的調用,使用這個設置后可以這樣調用:action!method --> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <!-- 指定jsp文件所在的目錄地址 --> <constant name="struts.convention.result.path" value="/WEB-INF/content/" /> <!-- 使用struts-default默認的轉換器,如果是rest的使用:rest-default,rest需要rest的jar插件 --> <constant name="struts.convention.default.parent.package" value="rest-default"/> <!-- 用於配置包名后綴。默認為action、actions、struts--> <constant name="struts.convention.package.locators" value="controller" /> <!-- 用於配置類名后綴,默認為Action,設置后,Struts2只會去找這種后綴名的類做映射 --> <constant name="struts.convention.action.suffix" value="Controller"/> <!-- 設置即使沒有@Action注釋,依然創建Action映射。默認值是false。因為Convention-Plugin是約定優於配置的風格, 可以不通過注解根據預先的定義就能訪問相應Action中的方法 --> <constant name="struts.convention.action.mapAllMatches" value="true"/> <!-- 自定義jsp文件命名的分隔符 --> <constant name="struts.convention.action.name.separator" value="-" /> <!-- 國際化資源文件名稱 --> <constant name="struts.custom.i18n.resources" value="i18n" /> <!-- 是否自動加載國際化資源文件 --> <constant name="struts.i18n.reload" value="true" /> <!-- 瀏覽器是否緩存靜態內容 --> <constant name="struts.serve.static.browserCache" value="false" /> <!-- 上傳文件大小限制設置 --> <constant name="struts.multipart.maxSize" value="-1" /> <!-- 主題,將值設置為simple,即不使用UI模板。這將不會生成額外的html標簽 --> <constant name="struts.ui.theme" value="simple" /> <!-- 編碼格式 --> <constant name="struts.i18n.encoding" value="UTF-8" /> </struts>
5) 新建設一個Controller的類:
package com.my.controller; import java.util.List; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.apache.struts2.rest.DefaultHttpHeaders; import org.apache.struts2.rest.HttpHeaders; import com.my.beans.User; import com.my.service.UserService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; @SuppressWarnings("serial") @Results(@Result(name = "success", type = "redirect", location="/user")) public class UserController extends ActionSupport implements ModelDriven<Object> { // Rest URL請求的ID值 private int id; // 用戶實體 private User model = new User(); // 用戶列表 private List<User> list; // 用戶Service private UserService userService = new UserService(); /** * 使用ModelDriven,重寫getModel()方法 */ @Override public Object getModel() { return (list != null ? list : model); } /** * 設置用戶ID * @param id */ public void setId(int id) { this.id = id; // 如果用戶ID大於零,取得用戶實體 if (id > 0) { this.model = userService.getId(id); } } /** * 取得用戶ID * @return */ public int getId() { return this.id; } /** * 功能:首頁 * 調用:GET /user * 返回:user-index.jsp * @return */ public HttpHeaders index() { list = userService.getAll(); return new DefaultHttpHeaders("index").disableCaching(); } /** * 功能:新增一個用戶 * 調用:GET /user/new * 返回:user-editNew.jsp * @return */ public String editNew() { model = new User(); return "editNew"; } /** * 功能:保存新增用戶 * 調用:POST /user * 返回:user-index.jsp * @return */ public HttpHeaders create() { userService.add(this.model); return new DefaultHttpHeaders(SUCCESS) .setLocationId(this.model.getId()); } /** * 功能:顯示用戶信息明細,返回show的jsp * 調用:GET /user/1 * 返回:user-show.jsp * @return */ public HttpHeaders show() { return new DefaultHttpHeaders("show"); } /** * 功能:編輯用戶 * 調用:GET /user/1/edit * 返回:user-edit.jsp * @return */ public String edit() { return "edit"; } /** * 功能:更新用戶信息 * 調用:PUT /user/1 * 返回:user-index.jsp * @return */ public String update() { userService.update(this.model); addActionMessage("Update user successed."); return SUCCESS; } /** * 功能:刪除用戶 * 調用:DELETE /user/1 * 返回:user-index.jsp * @return */ public String destroy() { userService.remove(id); addActionMessage("Delete user successed."); return SUCCESS; } }
注意這一句:@Results(@Result(name = "success", type = "redirect", location="/user"))
這句注解的意思是如果在方法中返回的是SUCCESS,則會將頁面重定向到這個地址:/user
不知道為什么,如果把type="redirect"改為type="redirectAction",它總會在地址后面加一個statusCode=303,然后會報一個錯誤。
AddActionMessage(...)方法調用后,在jsp中可以使用<s:actionmessage/>輸出內容。