SpringMVC(二)

1、綁定數組和List

一、綁定數組參數

經過id數組批量刪除java

<form action="${pageContext.request.contextPath }/deleteAll.action" method="post">
    <table width="100%" border=1>
        <tr>
            <td>
<
input type="submit" value="批量刪除"/>
       </
td> </tr> </table> <table width="100%" border=1> <c:forEach items="${itemList }" var="item" varStatus="status"> <tr> <!-- name屬性名稱要等於vo中的接收的id數組屬性名 --> <td> <input type="checkbox" name="ids" value="${item.id }"/> </td> </tr> </c:forEach> </table> </form>
// 窄化請求映射 localhost:8081/ssm0523-1/items/deleteAll.action
@RequestMapping("/items")
public class ItemsController {

    @Autowired
    private ItemsService itmesService;

    @RequestMapping("/deleteAll")
    public String delAll(QueryVo vo) throws Exception{
        //若是批量刪除,一堆input複選框,那麼能夠提交數組.(只有input複選框被選中的時候才能提交)
        System.out.println(vo);
        return "";    // 不跳轉頁面
    }
}

包裝類QueryVo中有private Integer[] ids屬性web

 

二、綁定List集合

經過List<Items>集合批量修改spring

包裝類QueryVo中有private List<Items> itemList;數據庫

<form action="${pageContext.request.contextPath }/updateAll.action" method="post">
<!-- status.index循環次數 -->
<c:forEach items="${itemList }" var="item" varStatus="status">
<table width="100%" border=1>
<tr>
    <!-- name屬性名稱要等於vo中的接收的屬性名 -->
    <!-- 若是批量刪除,能夠用List<pojo>來接收,頁面上input框的name屬性值= vo中接收的集合屬性名稱+[list的下標]+.+list泛型的屬性名稱 -->
    <td>
        <input type="checkbox" name="ids" value="${item.id }"/>
        <!-- 隱藏域,不顯示,可是提交 -->
        <input type="hidden" name="itemsList[${status.index }].id" value="${item.id }"/>
    </td>
    <td><input type="text" name="itemsList[${status.index }].name" value="${item.name }"/></td>
    <td><input type="text" name="itemsList[${status.index }].price" value="${item.price }"/></td>
    <td><input type="text" name="itemsList[${status.index }].createtime" 
               value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
    <td><input type="text" name="itemsList[${status.index }].detail" value="${item.detail }"/></td>
    
    <td><a href="${pageContext.request.contextPath }/items/itemEdit/${item.id}">修改</a></td>

</tr>
</table>
</c:forEach>
</form>
@RequestMapping("/updateAll")
public String updateAll(QueryVo vo) throws Exception{
    System.out.println(vo);
    return "";
}

 

2、@RequestMapping註解

定義不一樣的處理器映射規則json

一、請求URL路徑映射(加在方法上)數組

@RequestMapping(value="/item")或@RequestMapping("/item)tomcat

value的值是數組,能夠將多個url映射到同一個方法,只有一個值時能夠不寫valuesession

二、窄化請求路徑(加在類上)架構

@RequestMapping(value="/item")mvc

請求的URL前綴,類下全部的全部的方法都要加上此前綴,/item/itemList

三、限定請求方法

@RequestMapping(method = RequestMethod.GET)    限定GET方式

用POST報錯405

 

3、Controller方法返回值

指定返回到的頁面和返回到頁面的數據

一、ModelAndView

modelAndView.addObject("itemList", list); 指定返回頁面的數據

modelAndView.setViewName("itemList");  指定返回的頁面

二、String(推薦使用)

返回普通字符串,就是頁面去掉擴展名的名稱, 返回給頁面數據經過Model來完成

返回的字符串以forward:開頭爲請求轉發

返回的字符串以redirect:開頭爲重定向

三、返回void(使用它破壞了springMvc的結構,因此不建議使用)

可使用request.setAttribut 來給頁面返回數據

可使用request.getRquestDispatcher().forward()來指定返回的頁面

若是controller返回值爲void則不走springMvc的組件,因此要寫頁面的完整路徑名稱(/WEB-INF/)

 

相對路徑:相對於當前目錄,也就是在當前類的目錄下,這時候可使用相對路徑跳轉

絕對路徑:從項目名後開始

在springMvc中不論是forward仍是redirect後面凡是以/開頭的爲絕對路徑,不以/開頭的爲相對路徑

forward:/items/itemEdit.action 爲絕對路徑

forward:itemEdit.action爲相對路徑

 

4、異常處理(架構級別)

主要爲了防止項目上線後給用戶拋500等異常信息,因此須要在架構級別上總體處理.hold住異常
首先自定義全局異常處理器實現HandlerExceptionResolver接口
在spirngMvc.xml中配置生效

 

5、上傳圖片

一、配置虛擬目錄

在tomcat上配置圖片虛擬目錄,在tomcat下conf/server.xml中添加:

<Context docBase="F:\develop\upload\temp" path="/pic" reloadable="false"/>

訪問http://localhost:8080/pic便可訪問F:\develop\upload\temp下的圖片

也能夠經過eclipse配置

二、導包

CommonsMultipartResolver依賴commons-fileupload-1.2.2.jar、commons-io-2.4.jar

三、配置解析器

springmvc.xml中

<!--文件上傳 -->
    <bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--設置上傳文件的最大尺寸爲5MB -->
        <property name="maxUploadSize">
            <value>5242880</value>
        </property>
    </bean>

四、圖片上傳

@RequestMapping("/updateitem")
public String update(MultipartFile pictureFile,Items items, Model model, HttpServletRequest request) throws Exception{
    //1. 獲取圖片完整名稱
    String fileStr = pictureFile.getOriginalFilename();
    //2. 使用隨機生成的字符串+源圖片擴展名組成新的圖片名稱,防止圖片重名
    String newfileName = UUID.randomUUID().toString() + fileStr.substring(fileStr.lastIndexOf("."));
     //3. 將圖片保存到硬盤
    File uploadPic = new java.io.File("F:/develop/upload/temp/"+newFileName);
    if(!uploadPic.exists()){
    uploadPic.mkdirs();
    }
    pictureFile.transferTo(uploadPic);
    //4.將圖片名稱保存到數據庫
    items.setPic(newfileName);
    itmesService.updateItems(items);

    return "itemEdit"
}

五、JSP頁面

form添加enctype="multipart/form-data"

<form id="itemForm" action="${pageContext.request.contextPath }/item/editItemSubmit.action"
        method="post"enctype="multipart/form-data">
     <input type="hidden" name="pic" value="${item.pic }"/>
</form>

file的name與controller形參一致

<tr>
    <td>商品圖片</td>
    <td><c:if test="${item.pic !=null}">
        <imgsrc="/pic/${item.pic}" width=100 height=100 />
        <br/>
        </c:if><input type="file" name="pictureFile" /></td>
</tr>

 

六 JSON數據交互

 @RequestBody

將頁面傳到Controller中的JSON格式字符串自動轉換成java的POJO對象,並綁定到Controller方法的參數上

@ResponseBody

將Java中POJO對象自動轉換成JSON格式字符串返回給頁面,經過response響應給客戶端

@Controller
@RequestMapping("/items")
public class ItemsController {

    @Autowired
    private ItemsService itmesService;

    //導入jackson的jar包在 controller的方法中可使用@RequestBody,讓spirngMvc將json格式字符串自動轉換成java中的pojo
    //頁面json的key要等於java中pojo的屬性名稱
    //controller方法返回pojo類型的對象而且用@ResponseBody註解,springMvc會自動將pojo對象轉換成json格式字符串
    @RequestMapping("/sendJson")
    @ResponseBody
    public Items json(@RequestBody Items items) throws Exception{
        System.out.println(items);
        return items;
        }
}

 

7、Restful開發

資源定位及資源操做的風格,不是標誌,也不是協議,對HTTP協議的詮釋

就是對URL的命名標準,要求url中只有能名詞,沒有動詞(不嚴格要求),可是要求url中不能用問號?傳參
傳參數:
  頁面:${pageContext.request.contextPath }/items/itemEdit/${item.id}
  Controller方法中接收: @RquestMapping("/itemEdit/{id}")
  方法: @PathVariable("id") Integer idd

/**
*經過@PathVariable能夠接收url中傳入的參數 *@RequestMapping("/itemEdit/{id}")中接收參數使用大括號中加上變量名稱, @PathVariable中的變量名稱要和RequestMapping中的變量名稱相同 */ @RequestMapping("/itemEdit/{id}") 請求的URL public String itemEdit(@PathVariable("id") Integer id, HttpServletRequest reuqest, Model model) throws Exception{ @PathVariable得到URL的數據
}
${pageContext.request.contextPath }/items/itemEdit/${item.id}

 

8、攔截器

相似於Servlet開發中的過濾器Filter,用於對處理器進行預處理和後處理,通常作登陸權限驗證時用的比較多

一、須要編寫自定義攔截器類,實現HandlerInterceptor接口

二、在spirngMvc.xml中配置攔截器生效

實現HandlerInterceptor接口

public class Interceptor implements HandlerInterceptor{
    /**
     * controller執行前調用此方法,ModelAndView沒有被返回
     * 返回true表示繼續執行,返回false停止執行
     * 這裏能夠加入登陸校驗、權限攔截等
     */
    public boolean preHandle(HttpServletRequest request, 
        HttpServletResponse response, Object handler) throws Exception {
    }
    
    /**
     * controller執行後但未返回視圖ModelAndView前調用此方法
     * 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
     */
    public void postHandle(HttpServletRequest request, 
        HttpServletResponse response, Object handler, 
        ModelAndViewmodelAndView) throws Exception {
 }
  /**
     * controller執行後且視圖ModelAndView返回後調用此方法
     * 這裏可獲得執行controller時的異常信息
     * 這裏可記錄操做日誌,資源清理等
     */
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

springmvc.xml中配置攔截器

<mvc:interceptors>
        <!-- 可配置多個攔截器,順序執行 -->
    <mvc:interceptor>
        <!-- 攔截請求的路徑    要攔截全部必需配置成/** -->
        <mvc:mapping path="/**"/>
        <!-- 指定攔截器的位置 -->
        <bean class="cn.guojie.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

 

 

9、登陸權限驗證

一、編寫登陸的controller, 編寫跳轉到登陸頁面的方法,  編寫登陸驗證方法

二、編寫登陸頁面

三、編寫攔截器

運行過程:
(1)訪問隨意一個頁面,攔截器會攔截請求,會驗證session中是否有登陸信息
        若是已登陸,放行
        若是未登陸,跳轉到登陸頁面
(2)在登陸頁面中輸入用戶名,密碼,點擊登陸按鈕,攔截器會攔截請求,若是是登陸路徑放行
        在controller方法中判斷用戶名密碼是否正確,若是正確則將登陸信息放入session

@Controller
@RequestMapping("/login")
public class LoginController {

    //跳轉到登陸頁面
    @RequestMapping("/login")
    public String login() throws Exception{
        return "login";
    }
    
    @RequestMapping("/submit")
    public String submit(String username, String pwd ,HttpServletRequest request) throws Exception{
        
        HttpSession session = request.getSession();
        //判斷用戶名密碼的正確性,若是正確則將登陸信息放入session中
        //這裏簡寫,真正項目中須要去數據庫中校驗用戶名和密碼
        if(username != null){
            session.setAttribute("username", username);
        }
        
        //跳轉到列表頁顯示 重定向
        return "redirect:/items/list";
    }
}
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
        //判斷當前訪問路徑是否爲登陸的路徑,若是是則放行
        if(request.getRequestURI().indexOf("/login") > 0){
            return true;
        }
        
        //判斷session中是否有登陸信息,若是沒有則跳轉到登陸頁面,若是有則放行
        HttpSession session = request.getSession();
        if(session.getAttribute("username") != null){
            return true;
        }
        
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }

}

springmvc.xml中配置攔截器

<mvc:interceptors>
    <mvc:interceptor>
        <!-- 攔截請求的路徑    要攔截全部必需配置成/** -->
        <mvc:mapping path="/**"/>
        <!-- 指定攔截器的位置 -->
        <bean class="cn.guojie.interceptor.LoginInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>
<form action="${pageContext.request.contextPath }/login/submit" method="post">
<table>
    <tr><td>用戶名:<input name="username" type="text"/></td></tr>
    <tr><td>密碼:<input name="pwd" type="password"/></td></tr>
    <tr><td><input value="登陸" type="submit"/></td></tr>
</table>
</form>

只要有請求就會被先被攔截器攔截

請求,地址欄訪問 ----> 要直接是/login/login地址訪問就攔截放行跳到login.jsp,要地址不是 ----> 攔截器攔截判斷登陸路徑和登陸信息,都不知足,轉發到登陸頁面login.jsp去登陸 --->login.jsp頁面submit提交時重定向再次發請求,被攔截器攔截判斷登陸路徑,知足放行 ----> ${pageContext.request.contextPath }/login/submit請求到LoginController的submit方法中提交 ----> 重定向到商品列表頁,發送請求再次被攔截器攔截,登陸路徑不知足,但登陸信息有,放行

 

web.xml中

*.action:全部action後綴都攔截

/:攔截除JSP外全部,能夠不寫action

/*:攔截全部

相關文章
相關標籤/搜索