Struts2.0文件上傳:
瀏覽器端注意事項:javascript
1.表單提交方式method = post;前端
2.表單中必須有一個<input type="file" name = "upload">組件;java
3.表單中必須設置enctype="multipart/form-data";jquery
服務器端:android
Commons-fileupoad.jar c++
Struts2文件上傳實現:ajax
strust2框架是使用一個fileupload的interceptor來完成文件上傳,而咱們要使用它:spring
1.在action中咱們能夠提供相似一下的操做就能完成文件上傳操做:apache
public UploadAction extends ActionSupport{ private File upload; //上傳的文件 private String uploadContentType; //上傳文件的mimeType private String uploadFilename; //上傳文件的文件名
//對以上三個屬性實現get/set方法; }
注意:以上示例中的三個屬性名稱之間是有嚴格的命名規範的,upload名稱須要同前端表單<input type="file">組件中的name屬性值保持相同;第二個和第三個成員變量命名遵循第一個成員變量名稱+自身的名稱(ContentType/Filename);json
2.在Action的執行方法中將文件copy就能夠完成文件上傳。(strtus2.0框架提供了commons-io.jar包中有一個名爲FileUtils的工具類使用它來實現文件copy)
FileUtils.copyfile(File srcFile,File destFile);
Struts2文件上傳注意事項:
當咱們把a.txt文件後綴更改成png後,上傳出現問題,會報500空指針異常,而後咱們將action extends ActionSupport,再次上傳又會發現報404錯誤,而後咱們將struts2.0中一個常量struts.devMode設置爲true表示顯示詳細的錯誤報告,再次上傳會報404錯誤,而後咱們分析錯誤提示爲沒有定義一個input視圖。分析得:struts2.0默認加載18個intercptor,當這些個intercptor在執行過程當中若是出了問題,會將錯誤信息存儲到action中,而後由名爲workflow的interceptor執行跳轉到指定的input視圖。(爲何要extends ActionSupport,由於底層會調用ActionSupport中的addActionError等方法來傳遞錯誤信息)這時候咱們要查看錯誤信息,就須要在action中配置一個name值爲input的result標籤指定一個錯誤頁面,在錯誤頁面中使用<s:actionerror/><s:fielderror/>。。。來查看錯誤信息。
這時咱們看到這麼一條信息:
Request exceeded allowed size limit! Max size allowed is: 2097152 but request was:2283170!
錯誤信息顯示,上傳的文件信息過大
在default.properties中有一個常量值爲struts.multipart.maxSize = 2097152 (2m) 它是描述上傳文件容許的最大值,這時候咱們要在struts.xml中從新定義該常量值覆蓋掉這個常量值便可。
eg:<constant name = "struts.multipart.maxSize" value = "20971520"></constant> 這種設置方式爲全局設置在整個項目中生效,若是想單獨控制某個action的上傳文件大小或者文件類型,能夠在攔截器中定義,以下:
咱們還能夠控制文件上傳的類型。。。
查看FileUploadInterceptor攔截器有以下三個屬性:
maximumSize(文件大小);allowedTypesSet(文件MimeType類型);allowedExtensionsSet(文件的後綴名)
咱們能夠經過設置這三個屬性的值來控制文件上傳的具體屬性:
eg:
<action> <interceptor-ref name = "fileUpload"> <param name="maximumSize"></param> <!-- 設置action容許上傳文件的大小 --> <param name="allowedtypes"></param> <!-- 設置上傳容許的文件的mimetype類型,多個使用逗號分開 --> <param name="allowedtypes"></param> <!-- 設置上傳容許的文件的後綴名,多個使用逗號分開 --> </interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> <!-- 由於當咱們自行引入攔截器,那麼默認的18個攔截器就不會執行,在這裏要從新引入便可 -->
</action>
若是咱們上傳時,容許上傳多個文件,該如何?
客戶端:多個<input type="file" name=""/> 多個file組件的name屬性名要保持一致;
服務器端:
action中聲明的三個參數類型要變動爲數組或者List集合的類型:
eg:
public UploadAction extends ActionSupport{ private File[] upload; //上傳的文件 private String[] uploadContentType; //上傳文件的mimeType private String[] uploadFilename; //上傳文件的文件名 //對以上三個屬性實現get/set方法; }
action中實現文件copy使用遍歷:
eg:
public class uploadManyAction extends ActionSupport { private File[] upload; private String[] uploadContentType; private String[] uploadFileName; //對三個屬性實現get/set方法 public String execute() { String path = ServletActionContext.getServletContext().getRealPath("/upload"); for (int i = 0; i < upload.length; i++) { File dest = new File(path, uploadFileName[i]); FileUtis.copyFile(upload[i],dest); } } }
struts2框架的ajax開發:
json結構:
json就是javascript中的對象和數組,經過這兩種結構能夠表示各類複雜的結構;
1.對象:對象在js中表示爲「{ }」括起來的內容,數據結構爲{key:value,key:value,...}的鍵值對的結構,在面向對象的語言中,key對象的屬性,value爲對應的屬性值,因此取值方法爲 對象.key 獲取屬性值,這個屬性值的類型能夠是數字,字符串,數組,對象幾種。
2.數組:數組在js中是中括號"[ ]"括起來的內容,數據結構爲["android","javascript","c++",...]取值方式和全部語言中同樣,使用索引取值,字段值的類型能夠是數字,字符串,數組,對象幾種。
對象和數組之間能夠嵌套,這樣經果兩種數據結構的組合就造成了複雜的數據結構了。
java中json工具的介紹:(java數據和js數據之間的轉化)
Fastjson簡單使用介紹:
先導入fastjson的jar包
JSONObject.toJSONString(Object javabean);//將一個javabean轉換成json對象;
JSONArray.toJSONString(List<javabean> javabean);//將一個javabean的list集合轉換成json對象;
當須要對Date類型的字段進行格式化時須要在該字段上加上以下注釋:
@JSONField(format="yyyy-MM-dd")
當須要對數據進行過濾,如某些字段的數據不須要生成:
使用SerializaFilter接口的實現類PropertyFilter來實現屬性的過濾:
SerializeFilter filter = new Propertyfilter(){ @Override
/**
* arg0是要轉換成json的對象
* arg1是屬性名稱
* arg2是屬性值
* 當下面方法返回false,則不轉換該字段,返回true,則轉換該字段;
*/ public boolean apply(Obect arg0,String arg1,Object arg2){ if(arg1.equlas("columnFiledname")){ return false; } return true; } } String json = JSONObject.toJSONString(javabean,filter); //使用toJSONString(Object obj,SerializeFilter sf)重載函數
Jackson簡單使用介紹:
spring mvc 它底層使用的就是jackson
先導入jsckson的jar包;
ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(javabean);//將一個javabean或者javabean的list集合都可以轉換成json對象;
當須要對date日期格式進行格式化時能夠在上面兩行代碼中加入以下代碼便可:
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));//設置一個日期格式化器
過濾屬性:
在不須要的轉化的字段加上註解@JsonIgnore便可;
亦能夠在javabean上面加上註解@JsonIgnoreProperties({"comun1","comun2","comun3"...});
以上方法有缺陷,當有不一樣的需求須要生成不一樣的json數據,那麼就須要對javabean中字段進行不一樣的過濾,這時候就須要使用以下方法(硬編碼):
在javabean上加入註解@JsonFilter("beanFilter")
ObjectMapper mapper = new ObjectMapper(); FilterProvider fp = new SimpleFilterProvide().addFilter("beanFilter", SimpleBeanPropertyFilter.filterOutAllExcept("comun1","comun2"));//只包含comun1和comun2字段; //FilterProvider fp = new SimpleFilterProvide().addFilter("beanFilter", SimpleBeanPropertyFilter.serializeAllExcept("comun1","comun2"));//不包含comun1和comun2字段; mapper.setFilters(fp); String json = mapper.writeValueAsString(beanList);
struts2框架ajax開發使用response相應數據:
在struts2框架中獲取HttpServletResponse對象,就能夠經過response來完成將數據響應到瀏覽器;
瀏覽器端:
綁定事件,向服務器發送ajax請求(jquery完成)
服務器端:
action中能夠經過response來直接寫回數據,設置無返回值,或者返回null便可。
js中eval(String str)函數能夠將一個字符串轉換成對象;在使用ajax時,$.post()異步請求函數後面必定要加上"json"參數告訴瀏覽器這是json格式的數據,再者能夠使用eval函數將字符串轉爲json對象;
struts2框架ajax開發使用json插件來完成操做:
首先要導入插件包:struts2-json-plugin-版本號.jar
使用struts2提供的json插件三部曲:
struts加載配置文件的順序,會先加載插件包以後纔會加載咱們本身的struts.xml;
1.將咱們本身配置文件中的<package extends = "json-default"/> ;(json-default這個包在struts2-json-plugin.jar包中有)
2.Action的返回視圖<result name = "success" type = "json">;
3.由於咱們配置了上面兩步,那麼struts2框架就會將valueStack中棧頂元素轉換成json響應到瀏覽器,因此說咱們只須要將須要響應的數據 存入valueStack棧頂便可;
關於響應的json處理:
忽略屬性:
方法1:在須要忽略的屬性的get方法上面添加註解:@JSON(serialize=false)便可;
上面的方案有弊端,當不一樣的action須要響應不一樣的過濾數據時這樣就不通用了;
方法2:
在org.apache.struts2.json.JSONResult類中有兩個屬性:
private List<Pattern> includeProperties;
private List<Pattern> excludeProperties;
他們能夠設置響應的數據中是否包含或者不包含屬性:
<result name = "success" type = "json">
<param name = "excludeProperties">ps\[\d+\].屬性名,ps\[\d+\].屬性名...</param>
<!-- <param name = "includeProperties">ps\[\d+\].屬性名,ps\[\d+\].屬性名...</param> -->
</result>
設置root:
沒有設置root前返回的json結構 ps:[{},{}]
設置root它的根爲ps後的返回的json結構 [{},{}]
<result name = "success" type = "json">
<param name = "ps">ps</param>
<param name = "excludeProperties">\[\d+\].屬性名,ps\[\d+\].屬性名...</param>
<!-- <param name = "includeProperties">\[\d+\].屬性名,ps\[\d+\].屬性名...</param> -->
</result>
這樣響應到客戶端就是一個數組那麼取值能夠使用循環;
Struts2中配置文件struts.xml能夠分解各個模塊的xml文件,而後在struts.xml中使用<include>標籤引入便可,方便struts.xml的管理和閱讀。
Struts2.0註解開發:
struts2.0註解時在struts2的2.1版本後引入的,註解的做用就是用來替代原來struts.xml中的一些配置,如<package><action><result>.....等標籤;
使用註解開發首先須要導入struts2-convention-plugin-版本號.jar包;
爲什麼能識別到註解呢?
由於StrutsParparedAndExecuteFilter過濾器中在加載配置文件的時候會加載struts-plugin.xml插件配置文件,該配置文件中定義了一個名爲[struts.convention.package.Locators]的常量,它的值爲[action,actions,struts,struts2],也就是說系統會掃描符合的包名進行解析;若是須要更改這種命名規範的話,只須要在struts.xml文件中更改該常量值便可;
對於action能夠加以下註解來替代配置文件
註解位置 | 註解名稱 | 對應的配置文件 | 釋義 |
class | @Namespace("/") | <package namespace="/"> | |
class | @ParentPackage("struts-default") | <package extends="struts-default"> | |
class | @Results({@Result(name="",type="",location=""),@Result(name="",type="",location="")......}) | <global-results><result></global-results> | 全局result |
class | @InterceptorRefs({@InterceptorRef("interceptor-1"),@InterceptorRef("defaultStack")}) | ||
method | @Action(value="path",results={@Result(name="",type="",location=""),@Result(name="",type="",location="")......}) | <action name="path" class="" method=""><result> | |
method | @Action(value="",interceptorRefs=@InterceptorRef("validation")) | 它時用於處理攔截器的 | |
method | @Actions(@Action(),@Action(),@Action()......) | 能夠經過多個路徑來訪問同一個action |
使用註解開發完成自定義攔截器對頁面的權限控制
1.建立一個類來實現Interceptor接口或者繼承MethodFilterInterceptor;
2.在struts.xml文件中聲明;
eg:
<package name="base" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="自定義攔截器name" class = ""></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name = "自定義攔截器name"/>
<interceptor-ref name = "defaultStack"/>
</interceptor-stack>
</interceptors>
</package>
3.在action的配置中引用(使用註解):
eg:
@Namespace("/")
@ParentPackage("base")
public class ProductAction extends ActionSupport{
@Action(value="showProduct",interceptorRefs={@InterceptorRef("myStack")})
public void showProduct(){
......
}
}
注意@ParentPackage註解中的包名須要同配置文件中定義攔截器的包名相同。(如上兩個紅色標註)。