springmvc的簡單總結

框架原理

web層的知識結構導圖 

 

 

 

SpringMVC的各種參數綁定方式

1. 基本數據類型(以int爲例,其他類似):
Controller代碼:

@RequestMapping("saysth.do")
public void test(int count) {
}

表單代碼:

<form action="saysth.do" method="post">
<input name="count" value="10" type="text"/>
......
</form>

表單中input的name值和Controller的參數變量名保持一致,就能完成數據綁定,如果不一致可以使用@RequestParam註解。需要注意的是,如果Controller方法參數中定義的是基本數據類型,但是從頁面提交過來的數據爲null或者”"的話,會出現數據轉換的異常。也就是必須保證表單傳遞過來的數據不能爲null或”",所以,在開發過程中,對可能爲空的數據,最好將參數數據類型定義成包裝類型,具體參見下面的例子。

 

2. 包裝類型(以Integer爲例,其他類似):
Controller代碼:

@RequestMapping("saysth.do")
public void test(Integer count) {
}

表單代碼:

<form action="saysth.do" method="post">
<input name="count" value="10" type="text"/>
......
</form>

和基本數據類型基本一樣,不同之處在於,表單傳遞過來的數據可以爲null或”",以上面代碼爲例,如果表單中num爲”"或者表單中無num這個input,那麼,Controller方法參數中的num值則爲null。

 

3. 自定義對象類型:
Model代碼:

public class User {
    private String firstName;
    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

 

Controller代碼:

@RequestMapping("saysth.do")
public void test(User user) {
}

表單代碼:

<form action="saysth.do" method="post">
<input name="firstName" value="張" type="text"/>
<input name="lastName" value="三" type="text"/>
......
</form>

非常簡單,只需將對象的屬性名和input的name值一一匹配即可。

 

4. 自定義複合對象類型:
Model代碼:

public class ContactInfo {
    private String tel;
    private String address;

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

public class User {
    private String firstName;
    private String lastName;
    private ContactInfo contactInfo;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public ContactInfo getContactInfo() {
        return contactInfo;
    }

    public void setContactInfo(ContactInfo contactInfo) {
        this.contactInfo = contactInfo;
    }

}

 

Controller代碼:

@RequestMapping("saysth.do")
public void test(User user) {
    System.out.println(user.getFirstName());
    System.out.println(user.getLastName());
    System.out.println(user.getContactInfo().getTel());
    System.out.println(user.getContactInfo().getAddress());
}

 

表單代碼:

<form action="saysth.do" method="post">
<input name="firstName" value="張" /><br>
<input name="lastName" value="三" /><br>
<input name="contactInfo.tel" value="13809908909" /><br>
<input name="contactInfo.address" value="北京海淀" /><br>
<input type="submit" value="Save" />
</form>

 

User對象中有ContactInfo屬性,Controller中的代碼和第3點說的一致,但是,在表單代碼中,需要使用“屬性名(對象類型的屬性).屬性名”來命名input的name。

總結 :

   1.controller中的方法主要是用於參數  可以是簡單類型,pojo,包裝的pojo, 也可以是Httpsession,        HttpServletRequest,HttpServletResponse,Model

 

Controller方法返回值

返回void(和在servlet中一樣)

在Controller方法形參上可以義request和response,使用request或response指定響應結果:

1、使用request轉發頁面,如下:

request.getRequestDispatcher("頁面路徑").forward(request, response);

request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

 

2、可以通過response頁面重定向:

response.sendRedirect("url")

response.sendRedirect("/springmvc-web2/itemEdit.action");

 

  1. 可以通過response指定響應結果,例如響應json數據如下:
response.getWriter().print("{\"abc\":123}");
      1.  

返回字符串(轉發或是重定向寫在字符串中)

Redirect重定向

Contrller方法返回字符串可以重定向到一個url地址

如下商品修改提交後重定向到商品編輯頁面。

/**

 * 更新商品

 *

 * @param item

 * @return

 */

@RequestMapping("updateItem")

public String updateItemById(Item item) {

// 更新商品

this.itemService.updateItemById(item);



// 修改商品成功後,重定向到商品編輯頁面

// 重定向後瀏覽器地址欄變更爲重定向的地址,

// 重定向相當於執行了新的request和response,所以之前的請求參數都會丟失

// 如果要指定請求參數,需要在重定向的url後面添加 ?itemId=1 這樣的請求參數

return "redirect:/itemEdit.action?itemId=" + item.getId();

}

 

      1.  

forward轉發

Controller方法執行後繼續執行另一個Controller方法

如下商品修改提交後轉向到商品修改頁面,修改商品的id參數可以帶到商品修改方法中。

/**

 * 更新商品

 *

 * @param item

 * @return

 */

@RequestMapping("updateItem")

public String updateItemById(Item item) {

// 更新商品

this.itemService.updateItemById(item);



// 修改商品成功後,重定向到商品編輯頁面

// 重定向後瀏覽器地址欄變更爲重定向的地址,

// 重定向相當於執行了新的request和response,所以之前的請求參數都會丟失

// 如果要指定請求參數,需要在重定向的url後面添加 ?itemId=1 這樣的請求參數

// return "redirect:/itemEdit.action?itemId=" + item.getId();



// 修改商品成功後,繼續執行另一個方法

// 使用轉發的方式實現。轉發後瀏覽器地址欄還是原來的請求地址,

// 轉發並沒有執行新的request和response,所以之前的請求參數都存在

return "forward:/itemEdit.action";



}

//結果轉發到editItem.action,request可以帶過去

return "forward: /itemEdit.action";
  1.  

異常處理器

springmvc在處理請求過程中出現異常信息交由異常處理器進行處理,自定義異常處理器可以實現一個系統的異常處理邏輯。

 

    1. 自定義異常類

爲了區別不同的異常,通常根據異常類型進行區分,這裏我們創建一個自定義系統異常。

如果controller、service、dao拋出此類異常說明是系統預期處理的異常信息。

    1. 自定義異常處理器
public class CustomHandleException implements HandlerExceptionResolver {

@Override

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,

Exception exception) {

// 定義異常信息

String msg;

// 判斷異常類型

if (exception instanceof MyException) {

// 如果是自定義異常,讀取異常信息

msg = exception.getMessage();

} else {

// 如果是運行時異常,則取錯誤堆棧,從堆棧中獲取異常信息

Writer out = new StringWriter();

PrintWriter s = new PrintWriter(out);

exception.printStackTrace(s);

msg = out.toString();



}



// 把錯誤信息發給相關人員,郵件,短信等方式

// TODO

// 返回錯誤頁面,給用戶友好頁面顯示錯誤信息

ModelAndView modelAndView = new ModelAndView();

modelAndView.addObject("msg", msg);

modelAndView.setViewName("error");這個view是自己需要寫好的嗎??



return modelAndView;

}

}
    1. 異常處理器配置

在springmvc.xml中添加:

<!-- 配置全局異常處理器 -->

<bean 

id="customHandleException"  class="cn.itcast.ssm.exception.CustomHandleException"/>

</bean>

 

異常測試
修改ItemController方法“queryItemList”,拋出異常:



/**

 * 查詢商品列表

 *

 * @return

 * @throws Exception

 */

@RequestMapping(value = { "itemList", "itemListAll" })

public ModelAndView queryItemList() throws Exception {

// 自定義異常

if (true) {

throw new MyException("自定義異常出現了~");

}



// 運行時異常

int a = 1 / 0;



// 查詢商品數據

List<Item> list = this.itemService.queryItemList();

// 創建ModelAndView,設置邏輯視圖名

ModelAndView mv = new ModelAndView("itemList");

// 把商品數據放到模型中

mv.addObject("itemList", list);



return mv;

}
  1.  

上傳圖片

在tomcat上配置圖片虛擬目錄

 

訪問http://localhost:8080/pic圖片名  測試效果

    1. 配置上傳解析器

在springmvc.xml中配置文件上傳解析器

<!-- 文件上傳,id必須設置爲multipartResolver -->

<bean id="multipartResolver"

class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<!-- 設置文件上傳大小 -->

<property name="maxUploadSize" value="5000000" />

</bean>

 

    1. 圖片上傳

在更新商品方法中添加圖片上傳邏輯

    1. @RequestBody

作用:

@RequestBody註解用於讀取http請求的內容(字符串),通過springmvc提供的HttpMessageConverter接口將讀到的內容(json數據)轉換爲java對象並綁定到Controller方法的參數上。(之前傳入的都是字符串的形式的json數據  這裏一定要是json對象的數據)

    1. @ResponseBody

作用:

@ResponseBody註解用於將Controller的方法返回的對象,通過springmvc提供的HttpMessageConverter接口轉換爲指定格式的數據如:json,xml等,通過Response響應給客戶端

      1. ItemController編寫

 

/**

 * 測試json的交互

 * @param item

 * @return

 */

@RequestMapping("testJson")

// @ResponseBody

public @ResponseBody Item testJson(@RequestBody Item item) {

return item;

}

 

<mvc:annotation-driven />:解析:@RequestMapping("testJson")  @ResponseBody   @RequestBody 等註解

總結:
我們前臺請求過去的json字符串,在使用@RequestBody註解後 被HttpMessageConverter,轉換成對應的java對象,然後我們在用@ResponseBody註解,將java對象 以特定的格式(通常都是json)相應給瀏覽器。

 

關於@ResponseBody與@RequestBody註解的用法可以參考這篇博客:https://blog.csdn.net/weixin_43732955/article/details/92843116

 

攔截器

實現HandlerInterceptor接口,如下:

public class HandlerInterceptor1 implements HandlerInterceptor {

// controller執行後且視圖返回後調用此方法

// 這裏可得到執行controller時的異常信息

// 這裏可記錄操作日誌

@Override

public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)

throws Exception {

System.out.println("HandlerInterceptor1....afterCompletion");

}



// controller執行後但未返回視圖前調用此方法

// 這裏可在返回用戶前對模型數據進行加工處理,比如這裏加入公用信息以便頁面顯示

@Override

public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)

throws Exception {

System.out.println("HandlerInterceptor1....postHandle");

}



// Controller執行前調用此方法

// 返回true表示繼續執行,返回false中止執行

// 這裏可以加入登錄校驗、權限攔截等

@Override

public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {

System.out.println("HandlerInterceptor1....preHandle");

// 設置爲true,測試使用

return true;

}

}
    1. 攔截器配置

上面定義的攔截器再複製一份HandlerInterceptor2,注意新的攔截器修改代碼:

System.out.println("HandlerInterceptor2....preHandle");

 

在springmvc.xml中配置攔截器

<!-- 配置攔截器 -->

<mvc:interceptors>

<mvc:interceptor>

<!-- 所有的請求都進入攔截器 -->

<mvc:mapping path="/**" />

<!-- 配置具體的攔截器 -->

<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />

</mvc:interceptor>

<mvc:interceptor>

<!-- 所有的請求都進入攔截器 -->

<mvc:mapping path="/**" />

<!-- 配置具體的攔截器 -->

<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />

</mvc:interceptor>

</mvc:interceptors>

日期轉換問題

前端傳過來是string類型   但是pojo中是date  如何進行對象映射

(一般pojo也會是string類型不會寫成date)

由於日期數據有很多種格式,springmvc沒辦法把字符串轉換成日期類型。所以需要自定義參數綁定。

 

前端控制器接收到請求後,找到註解形式的處理器適配器,對RequestMapping標記的方法進行適配,並對方法中的形參進行參數綁定。可以在springmvc處理器適配器上自定義轉換器Converter進行參數綁定。

 

一般使用<mvc:annotation-driven/>註解驅動加載處理器適配器,可以在此標籤上進行配置。

 

      1. 修改jsp頁面

如下圖修改itemEdit.jsp頁面,顯示時間

 

      1. 自定義Converter
//Converter<S, T>

//S:source,需要轉換的源的類型

//T:target,需要轉換的目標類型

public class DateConverter implements Converter<String, Date> {



@Override

public Date convert(String source) {

try {

// 把字符串轉換爲日期類型

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");

Date date = simpleDateFormat.parse(source);

return date;

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// 如果轉換異常則返回空

return null;

}

}

      1. 配置Converter

我們同時可以配置多個的轉換器。

類似下圖的usb設備,可以接入多個usb設備

<!-- 配置註解驅動 -->

<!-- 如果配置此標籤,可以不用配置... -->

<mvc:annotation-driven conversion-service="conversionService" />



<!-- 轉換器配置 -->

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

<property name="converters">

<set>

<bean class="cn.itcast.springmvc.converter.DateConverter" />

</set>

</property>

</bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章