Java Web,SpringMVC_02

 2023-10-17 阅读 24 评论 0

摘要:響應數據和結果視圖 返回值分類 返回字符串 Controller方法返回字符串可以指定邏輯視圖的名稱,根據視圖解析器為物理視圖的地址。 @RequestMapping(value="/hello") public String sayHello() {System.out.println("Hello SpringMVC!!");// 跳

響應數據和結果視圖

返回值分類

  1. 返回字符串
  • Controller方法返回字符串可以指定邏輯視圖的名稱,根據視圖解析器為物理視圖的地址。
@RequestMapping(value="/hello")
public String sayHello() {System.out.println("Hello SpringMVC!!");// 跳轉到XX頁面return "success"; 
}
  • 具體的應用場景
@Controller
@RequestMapping("/user")
public class UserController {/*** 請求參數的綁定*/@RequestMapping(value="/initUpdate")public String initUpdate(Model model) {// 模擬從數據庫中查詢的數據User user = new User();user.setUsername("張三");user.setPassword("123");user.setMoney(100d);user.setBirthday(new Date());model.addAttribute("user", user);return "update";}
}
<h3>修改用戶</h3>
${requestScope}
<form action="user/update" method="post">姓名:<input type="text" name="username" value="${ user.username }"><br>密碼:<input type="text" name="password" value="${ user.password }"><br>金額:<input type="text" name="money" value="${ user.money }"><br>
<input type="submit" value="提交">
</form>

  1. 返回值是void
    1. 如果控制器的方法返回值編寫成void,執行程序報404的異常,默認查找JSP頁面沒有找到。
      默認會跳轉到@RequestMapping(value="/initUpdate") initUpdate的頁面。
    2. 可以使用請求轉發或者重定向跳轉到指定的頁面
@RequestMapping(value="/initAdd")
public void initAdd(HttpServletRequest request,HttpServletResponse response) throws Exception {System.out.println("請求轉發或者重定向");
// 請求轉發
// request.getRequestDispatcher("/WEB-INF/pages/add.jsp").forward(request,response);
// 重定向
// response.sendRedirect(request.getContextPath()+"/add2.jsp");response.setCharacterEncoding("UTF-8");response.setContentType("text/html;charset=UTF-8");
// 直接響應數據response.getWriter().print("你好");return;}

  1. 返回值是ModelAndView對象
    1. ModelAndView對象是Spring提供的一個對象,可以用來調整具體的JSP視圖
    2. 具體的代碼如下
/*** 返回ModelAndView對象* 可以傳入視圖的名稱(即跳轉的頁面),還可以傳入對象。* @return* @throws Exception*/
@RequestMapping(value="/findAll")
public ModelAndView findAll() throws Exception {ModelAndView mv = new ModelAndView();// 跳轉到list.jsp的頁面mv.setViewName("list");// 模擬從數據庫中查詢所有的用戶信息List<User> users = new ArrayList<>();User user1 = new User();user1.setUsername("張三");user1.setPassword("123");User user2 = new User();user2.setUsername("趙四");user2.setPassword("456");users.add(user1);users.add(user2);// 添加對象mv.addObject("users" , users);}

SpringMVC框架提供的轉發和重定向

  1. forward請求轉發
    1. controller方法返回String類型,想進行請求轉發也可以編寫成
/*** 使用forward關鍵字進行請求轉發* "forward:轉發的JSP路徑",不走視圖解析器了,所以需要編寫完整的路徑* @return* @throws Exception*/
@RequestMapping("/delete")
public String delete() throws Exception {System.out.println("delete方法執行了...");// return "forward:/WEB-INF/pages/success.jsp";return "forward:/user/findAll";
}

  1. redirect重定向
    1. controller方法返回String類型,想進行重定向也可以編寫成
/*** 重定向* @return* @throws Exception*/
@RequestMapping("/count")
public String count() throws Exception {System.out.println("count方法執行了... ");return "redirect:/add.jsp";// return "redirect:/user/findAll";}

ResponseBody響應json數據

  • 需求:
    使用@ResponseBody 注解實現將 controller 方法返回對象轉換為 json 響應給客戶端。
  • 前置知識點:
    Springmvc 默認用MappingJacksonHttpMessageConverter 對 json 數據進行轉換,需要加入jackson 的包。
    注意:2.7.0 以下的版本用不了
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.0</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version>
</dependency>

注意:2.7.0 以下的版本用不了

  • DispatcherServlet會攔截到所有的資源,導致一個問題就是靜態資源(img、css、js)也會被攔截到,從而不能被使用。解決問題就是需要配置靜態資源不進行攔截,在springmvc.xml配置文件添加如下配置
    mvc:resources標簽配置不過濾
    1. location元素表示webapp目錄下的包下的所有文件
    2. mapping元素表示以/static開頭的所有請求路徑,如/static/a 或者/static/a/b
<!-- 設置靜態資源不過濾 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 樣式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 圖片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->
  • 使用@RequestBody注解把json的字符串轉換成JavaBean的對象
// 頁面加載
// 頁面加載
$(function(){
// 綁定點擊事件$("#btn").click(function(){$.ajax({url:"user/testJson",contentType:"application/json;charset=UTF-8",data:'{"addressName":"aa","addressNum":100}',dataType:"json",type:"post",success:function(data){alert(data);alert(data.addressName);}});});
});
/*** 獲取請求體的數據* @param body*/
@RequestMapping("/testJson")
public void testJson(@RequestBody Address address) {System.out.println(address);}
  • 使用@ResponseBody注解把JavaBean對象轉換成json字符串,直接響應
    • 要求方法需要返回JavaBean的對象
@RequestMapping("/testJson")
public @ResponseBody Address testJson(@RequestBody Address address) {System.out.println(address);address.setAddressName("上海");return address;
}



SpringMVC實現文件上傳

文件上傳的必要前提

  • A form 表單的 enctype 取值必須是:multipart/form-data
    • (默認值是:application/x-www-form-urlencoded)
    • enctype:是表單請求正文的類型
  • B method 屬性取值必須是Post
  • C 提供一個文件選擇域<input type=”file” />

文件上傳的原理分析

  • Java Web?當 form 表單的 enctype 取值不是默認值后,request.getParameter()將失效。

  • enctype=”application/x-www-form-urlencoded”時,form 表單的正文內容是:

key=value&key=value&key=value

  • 當 form 表單的 enctype 取值為 Mutilpart/form-data 時,請求正文內容就變成:
    每一部分都是 MIME 類型描述的正文

springMVC重定向、-----------------------------7de1a433602ac 分界符
Content-Disposition: form-data; name=“userName” 協議頭
aaa 協議的正文
-----------------------------7de1a433602ac
Content-Disposition: ?? form-data; ????name=“file”;
filename=“C:\Users\zhy\Desktop\fileupload_demofile\b.txt”
Content-Type: text/plain 協議的類型(MIME 類型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
-----------------------------7de1a433602ac–

借助第三方組件實現文件上傳

  1. 使用 Commons-fileupload 組件實現文件上傳,需要導入該組件相應的支撐 jar 包:Commons-fileupload 和commons-io。commons-io 不屬于文件上傳組件的開發 jar 文件,但Commons-fileupload 組件從 1.1 版本開始,它工作時需要 commons-io 包的支持。
    在這里插入圖片描述
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version>
</dependency>
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency>
  1. 編寫文件上傳的JSP頁面
<h3>文件上傳</h3>
<form action="user/fileupload" method="post" enctype="multipart/form-data">選擇文件:<input type="file" name="upload"/><br/><input type="submit" value="上傳文件"/>
</form>
  1. 編寫文件上傳的Controller控制器
 /*** 文件上傳* @return*/@RequestMapping("/fileupload1")public String fileuoload1(HttpServletRequest request) throws Exception {System.out.println("文件上傳...");// 使用fileupload組件完成文件上傳// 上傳的位置String path = request.getSession().getServletContext().getRealPath("/uploads/");// 判斷,該路徑是否存在File file = new File(path);if(!file.exists()){// 創建該文件夾file.mkdirs();}// 解析request對象,獲取上傳文件項DiskFileItemFactory factory = new DiskFileItemFactory();ServletFileUpload upload = new ServletFileUpload(factory);// 解析requestList<FileItem> items = upload.parseRequest(request);// 遍歷for(FileItem item:items){// 進行判斷,當前item對象是否是上傳文件項if(item.isFormField()){// 說明普通表單向}else{// 說明上傳文件項// 獲取上傳文件的名稱String filename = item.getName();// 把文件的名稱設置唯一值,uuidString uuid = UUID.randomUUID().toString().replace("-", "");filename = uuid+"_"+filename;// 完成文件上傳item.write(new File(path,filename));// 刪除臨時文件item.delete();}}return "success";}

SpringMVC傳統方式文件上傳

  1. SpringMVC框架提供了MultipartFile對象,該對象表示上傳的文件,要求變量名稱必須和表單file標簽的name屬性名稱相同。
  2. 代碼如下
 /*** SpringMVC文件上傳* @return*/@RequestMapping("/fileupload2")public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {System.out.println("springmvc文件上傳...");// 使用fileupload組件完成文件上傳// 上傳的位置String path = request.getSession().getServletContext().getRealPath("/uploads/");// 判斷,該路徑是否存在File file = new File(path);if(!file.exists()){// 創建該文件夾file.mkdirs();}// 說明上傳文件項// 獲取上傳文件的名稱String filename = upload.getOriginalFilename();// 把文件的名稱設置唯一值,uuidString uuid = UUID.randomUUID().toString().replace("-", "");filename = uuid+"_"+filename;// 完成文件上傳upload.transferTo(new File(path,filename));return "success";}
  1. 配置文件解析器對象
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="10485760"/>
</bean>

SpringMVC跨服務器方式文件上傳

  1. 搭建圖片服務器
    1. 根據文檔配置tomcat9的服務器,現在是2個服務器
    2. 導入資料中day02_springmvc5_02image項目,作為圖片服務器使用
  2. 實現SpringMVC跨服務器方式文件上傳
    1. 導入開發需要的jar包
    2. 編寫文件上傳的JSP頁面
    3. 編寫控制器
	<!--1. 導入開發需要的jar包-->
<dependency><groupId>com.sun.jersey</groupId><artifactId>jersey-core</artifactId><version>1.18.1</version>
</dependency>
<dependency><groupId>com.sun.jersey</groupId><artifactId>jersey-client</artifactId><version>1.18.1</version>
</dependency>
<!--2. 編寫文件上傳的JSP頁面-->
<h3>跨服務器的文件上傳</h3>
<form action="user/fileupload3" method="post" enctype="multipart/form-data">選擇文件:<input type="file" name="upload"/><br/><input type="submit" value="上傳文件"/>
</form>
 /**	3. 編寫控制器* 跨服務器文件上傳* @return*/@RequestMapping("/fileupload3")public String fileuoload3(MultipartFile upload) throws Exception {System.out.println("跨服務器文件上傳...");// 定義上傳文件服務器路徑String path = "http://localhost:9090/uploads/";// 說明上傳文件項// 獲取上傳文件的名稱String filename = upload.getOriginalFilename();// 把文件的名稱設置唯一值,uuidString uuid = UUID.randomUUID().toString().replace("-", "");filename = uuid+"_"+filename;// 創建客戶端的對象Client client = Client.create();// 和圖片服務器進行連接WebResource webResource = client.resource(path + filename);// 上傳文件webResource.put(upload.getBytes());return "success";}



SpringMVC的異常處理

異常處理的思路

  • 系統中異常包括兩類:預期異常和運行時異常 RuntimeException,前者通過捕獲異常從而獲取異常信息,后者主要通過規范代碼開發、測試通過手段減少運行時異常的發生。
  • 系統的 dao、service、controller 出現都通過 throws Exception 向上拋出,最后由 springmvc 前端控制器交由異常處理器進行異常處理,如下圖:
    在這里插入圖片描述

實現步驟

  1. 自定義異常類
package cn.myp666.exception;/*** 自定義異常類*/
public class SysException extends Exception{// 存儲提示信息的private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public SysException(String message) {this.message = message;}}
  1. 自定義異常處理器
/*** 異常處理器*/
public class SysExceptionResolver implements HandlerExceptionResolver{/*** 處理異常業務邏輯* @param request* @param response* @param handler* @param ex* @return*/public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 獲取到異常對象SysException e = null;if(ex instanceof SysException){e = (SysException)ex;}else{e = new SysException("系統正在維護....");}// 創建ModelAndView對象ModelAndView mv = new ModelAndView();// 存入錯誤的提示信息mv.addObject("errorMsg",e.getMessage());// 跳轉的Jsp頁面mv.setViewName("error");return mv;}}
  1. 配置異常處理器
<!-- 配置異常處理器 -->
<bean id="sysExceptionResolver" class="cn.myp666.exception.SysExceptionResolver"/>



SpringMVC 中的攔截器

攔截器的概述

  1. SpringMVC框架中的攔截器用于對處理器進行預處理和后處理的技術。
  2. 可以定義攔截器鏈,連接器鏈就是將攔截器按著一定的順序結成一條鏈,在訪問被攔截的方法時,攔截器鏈
    中的攔截器會按著定義的順序執行。
  3. 攔截器和過濾器的功能比較類似,有區別
    1. 過濾器是Servlet規范的一部分,任何框架都可以使用過濾器技術。
    2. 攔截器是SpringMVC框架獨有的。
    3. 過濾器配置了/*,可以攔截任何資源。
    4. 攔截器只會對控制器中的方法進行攔截。
  4. 攔截器也是AOP思想的一種實現方式
  5. 想要自定義攔截器,需要實現HandlerInterceptor接口。

自定義攔截器步驟

  1. 創建類,實現HandlerInterceptor接口,重寫需要的方法
package cn.myp666.demo1;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
/*** 自定義攔截器1* @author rt*/
public class MyInterceptor1 implements HandlerInterceptor{/*** controller方法執行前,進行攔截的方法* return true放行* return false攔截* 可以使用轉發或者重定向直接跳轉到指定的頁面。*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {System.out.println("攔截器執行了...");return true;}
}
  1. 在springmvc.xml中配置攔截器類
<!-- 配置攔截器 -->
<mvc:interceptors><mvc:interceptor><!-- 哪些方法進行攔截 --><mvc:mapping path="/user/*"/><!-- 哪些方法不進行攔截<mvc:exclude-mapping path=""/>	--><!-- 注冊攔截器對象 --><bean class="cn.myp666.demo1.MyInterceptor1"/></mvc:interceptor>
</mvc:interceptors>

HandlerInterceptor接口中的方法

  1. preHandle方法是controller方法執行前攔截的方法
    1. 可以使用request或者response跳轉到指定的頁面
    2. return true放行,執行下一個攔截器,如果沒有攔截器,執行controller中的方法。
    3. return false不放行,不會執行controller中的方法。
  2. postHandle是controller方法執行后執行的方法,在JSP視圖執行前。
    1. 可以使用request或者response跳轉到指定的頁面
    2. 如果指定了跳轉的頁面,那么controller方法跳轉的頁面將不會顯示。
  3. postHandle方法是在JSP執行后執行
    1. request或者response不能再跳轉頁面了
  • 示例:
package cn.myp666.controller.cn.myp666.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器*/
public class MyInterceptor1 implements HandlerInterceptor{/*** 預處理,controller方法執行前* return true 放行,執行下一個攔截器,如果沒有,執行controller中的方法* return false不放行* @param request* @param response* @param handler* @return* @throws Exception*/public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("MyInterceptor1執行了...前1111");// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);return true;}/*** 后處理方法,controller方法執行后,success.jsp執行之前* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyInterceptor1執行了...后1111");// request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);}/*** success.jsp頁面執行后,該方法會執行* @param request* @param response* @param handler* @param ex* @throws Exception*/public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("MyInterceptor1執行了...最后1111");}}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/143601.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息