文章目錄
一、Spring MVC響應視圖
Spring MVC 支持多種視圖響應方式,包括字符串類型、ModelAndView 類型、JSON 類型
1、以字符串的方式響應網頁
在 Spring MVC 的業務控制器方法中,如果返回值爲 String 類型,同時處理方式沒有定義爲 JSON 方式,那麼 Spring MVC 將會將該字符串的值作爲網頁地址或者邏輯視圖來處理。
例如:
@RequestMapping("test")
public String test() {
return "success.jsp";
}
在上述方法中最終返回值是 success.jsp,那麼 Spring-mvc 將以相對路徑的方式去查找 success.jsp 網頁並響應。
爲了便於響應網頁文件,Spring-mvc 提供了視圖解析器,只返回一個邏輯視圖名稱的時候,視圖解析器會把該邏輯視圖名稱解析爲真正的視圖 View 對象,視圖解析器的配置如下,在 Spring-mvc 的配置文件中,使用 bean 標籤加載視圖解析器:
<!--配置視圖解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
這樣在 Controller 層就可以直接返回 success
@RequestMapping("test")
public String test() {
return "success";
}
prefix 爲網頁所在邏輯視圖追加的前綴,suffix 爲邏輯視圖追加的後綴。例如我們在方法中返回 success,那麼視圖解析器通過解析之後在 success 邏輯視圖上添加上前綴和後綴,最後響應的網頁地址爲/success.jsp
。
在定義了視圖解析器的情況下,依然可以在返回值中使用網頁文件的完整路徑進行響應。默認情況下視圖解析器將會採用轉發的方式響應網頁信息,可以在邏輯視圖名稱進行修飾,進行轉發或者重定向。
return "redirect:success.jsp"; //重定向
return "forward:success.jsp"; //轉發
如果要手動定義轉發或者重定向,那麼返回值中就不能寫邏輯視圖必須寫網頁文件的路徑
如果需要在響應的 jsp 中使用動態數據,我們可以將 request 對象綁定包方法的形參中,然後將數據保存在 request 作用域中進行響應。
2、響應 ModelAndView 對象
在 web 項目中如果要響應網頁信息,那麼網頁中通常都包含了動態數據,Spring-mvc 專門提供了一種包含數據的視圖解析方式,也就是 ModelAndView。
ModelAndView 是 Spring-mvc 中的一個類,該類可以同時指定視圖地址和需要保存到 request 作用域中的數據
@RequestMapping("test")
public ModelAndView test() {
ModelAndView mav = new ModelAndView();
mav.setViewName("success.jsp");
mav.addObject("name", "張三");
return mav;
}
addObject(key,value)
方法用於指定要保存到 request 作用域中的數據,key 最終會作爲 request 作用域中數據的鍵。
addObject(value)
方法用於指定要保存到 request 作用域中的數據,如果保存的是一個實體類對象,那麼key=實體類對象類名首字母小寫
,如果保存的是一個集合數據,那麼key=集合的泛型首字母小寫+List
。
3、響應 JSON 數據
Spring-mvc 也可以響應 json 類型的數據,步驟非常的簡單。
(1)導入 jackson 相關包
(2)需要將什麼數據使用 json 的方式響應給客戶端,就將方法的返回值定義爲該數據類型,例如:想將 Users 對象數據以 json 的形式響應給客戶端,方法的返回值就定義爲 Users 類型,如果想響應一個 Users 類型的集合數據,就將方法的返回值定義爲集合類型。
public Users test() {
Users users = new Users();
users.setUserName("張三");
users.setUserPassword("zhangsan");
return users;
}
(3)在方法上添加註解,@ResponseBody
表示該方法的返回值將採用 json 的形式返回給客戶端。
@RequestMapping(value="test")
@ResponseBody
public Users test() {
Users users = new Users();
users.setUserName("張三");
users.setUserPassword("zhangsan");
return users;
}
(4)如果一個業務控制器中的所有方法都採用 json 的方式響應數據,那麼可以在類上使用全局的設置,將@Controller
註解替換爲@RestController
,如此就不需要在每一個方法上都添加@ResponseBody
註解。
@RestController
public class UserController {
@RequestMapping(value="test")
public Users test() {
Users users = new Users();
users.setUserName("張三");
users.setUserPassword("zhangsan");
return users;
}
}
(4)響應 JSON 示例
① 前端 ajax 請求
<script type="text/javascript">
$.ajax({
url: "ajax.do",
type: "post",
data: {"id":1},
dataType: "json",
success:function(data){
for(var i = 0; i < data.list.length; i++){
console.log(data.list[i].userName);
}
}
});
</script>
② Controller 層
@Controller
public class UserController {
@RequestMapping("ajax")
@ResponseBody
public ResultModel ajax(int id) {
System.out.println(id);
Users users1 = new Users();
users1.setUserName("張三");
Users users2 = new Users();
users2.setUserName("李四");
Users users3 = new Users();
users3.setUserName("王五");
List<Users> list = new ArrayList<Users>();
list.add(users1);
list.add(users2);
list.add(users3);
return new ResultModel(list, null, "success", null);
}
}
③ ResultModel 實體類
public class ResultModel {
private List list; //集合封裝
private Object object; //對象封裝
private String code; //反饋信息
private String message; //顯示錯誤信息
public ResultModel() {}
public ResultModel(List list, Object object, String code, String message) {
this.list = list;
this.object = object;
this.code = code;
this.message = message;
}
//省略set、get方法
}
二、Spring MVC 統一異常處理
在編程過程中異常處理往往是一件很麻煩的事情,Spring-mvc 提供了異常處理器,在設計程序時每一層的異常不需要自己處理,而是選擇逐層的拋出,也就是dao->service->controller->異常處理器
,最終在異常處理器中對異常進行統一的處理。
1、普通請求方式異常處理
(1)自定義異常處理器類
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error.jsp");
mav.addObject("message", "服務器內部錯誤");
return mav;
}
}
(2)根據視圖解析器的配置在項目中新建錯誤頁面
<body>
錯誤界面
${message}
</body>
(3)加載異常處理器
① 第一種方式:
<!-- 配置異常處理加載器 -->
<bean class="com.springmvc.demo1.exception.ExceptionResolver"></bean>
② 第二種方式
在自定義異常處理器類上添加@Component
註解
@Component
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error");
return mav;
}
}
然後通過配置掃描實體類的地址的配置進行自定義異常處理類的加載
<context:component-scan base-package="com.springmvc.demo1.exception"></context:component-scan>
(4)在控制層中定義方法時,將異常拋出
@Controller
public class UserController throws Exception {
@RequestMapping("test")
public String test() throws Exception{
System.out.println("自定義異常處理器");
//觸發異常
int i = 1/0;
return "success.jsp";
}
}
2、AJAX 請求方式異常處理
(1)導入 fastjson 的 jar 包
(2)自定義異常處理器類
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
FastJsonJsonView view = new FastJsonJsonView();
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", "error.jsp");
map.put("message", "服務器內部錯誤");
view.setAttributesMap(map);
ModelAndView mav = new ModelAndView();
mav.setView(view);
return mav;
}
}
(3)ajax 請求頁面
<body>
<script type="text/javascript">
$.ajax({
url: "ajax.do",
type: "post",
data: {"id":1},
dataType: "json",
success:function(data){
console.log(data);
}
});
</script>
</body>
(4)加載異常處理器(與普通類請求一樣)
① 第一種方式:
<!-- 配置異常處理加載器 -->
<bean class="com.springmvc.demo1.exception.ExceptionResolver"></bean>
② 第二種方式
在自定義異常處理器類上添加@Component
註解
@Component
public class ExceptionResolver implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex) {
ModelAndView mav = new ModelAndView();
mav.setViewName("error");
return mav;
}
}
然後通過配置掃描實體類的地址的配置進行自定義異常處理類的加載
<context:component-scan base-package="com.springmvc.demo1.exception"></context:component-scan>
(5)在控制層中定義方法時,將異常拋出
@Controller
public class UserController {
@RequestMapping("ajax")
@ResponseBody
public String ajax(int id) {
int i = 1 / 0;
return "success.jsp";
}
}