SpringMVC框架入門教程
整理自一個文件 作者:郝文龍 部落格首頁:https://me.csdn.net/a639735331
1.MVC
2.SpringMVC執行流程
Spring MVC是結構最清晰的MVC實現。Controller接收請求,然後返回ModelAndView。
1.springmvc將所有的請求都提交給DispatcherServlet,它會委託應用系統的其他模組負責對請求進行真正的處理工作。
2.DispatcherServlet查詢HandlerMapping,找到處理請求的Controller。
3.DispatcherServlet將請求提交到目標Controller。
4.Controller進行業務邏輯處理後,會返回一個ModelAndView。
5.Dispathcher查詢ViewResolver檢視解析器,找到ModelAndView物件指定的檢視物件。
6.將頁面渲染到瀏覽器客戶端。
3.常見MVC框架比較
執行效能上:
Jsp+servlet+javabean>spring mvc>struts2。
開發效率上,基本正好相反。值得強調的是,spring mvc開發效率和struts2不相上下。
4.環境搭建
4.1.下載zip包spring-framework-3.2.4.RELEASE-dist.zip (不支援jdk1.8)
4.2.解壓到指定目錄
4.3.建立web專案並加入jar包
注意:commons-logging-1.0.4.jar需單獨下載
4.4. 建立HelloWorldController
@Controller public class HelloWorldController { @RequestMapping("/helloWorld.do") public String helloWorld(){ return "welcome.jsp"; } } |
4.5. 在 src下建立spring的配置檔案spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd "> <!-- 啟動spring自動掃描,注入bean --> <context:component-scan base-package="com.niit.springmvc"/> <!-- 啟用springmvc註解功能 --> <mvc:annotation-driven /> </beans> |
4.6.配置web.xml
<servlet> <servlet-name>example</servlet-name> <!--Spring MVC裡的前端控制器DispatcherServlet就是一個Servlet --> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- 載入spring核心配置檔案 --> <param-name>contextConfigLocation</param-name> <!--param-value是Spring MVC配置檔案的路徑 --> <param-value>classpath:spring-servlet.xml</param-value> </init-param> <!--啟動級別為1,當Tomcat啟動時,應用也隨之啟動 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>example</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
4.7.新增welcome.jsp
4.8.測試請求: http://localhost:8080/HelloWorld/helloWorld.do
5. RequestMapping註解
[email protected]用來定義訪問的URL,你可以為整個類定義一個@RequestMapping,或者為每個方法指定一個。
把@RequestMapping放在類級別上,這可令它與方法級別上的@RequestMapping註解協同工作,取得縮小選擇範圍的效果。 例如:
@RequestMapping("/test") |
該類下的所有訪問路徑都在/test之下。
2.將@RequestMapping用於整個類不是必須的,如果沒有配置,則直接參考方法的註解匹配對應的url。
3.完整的引數項為:@RequestMapping(value="",method ={"",""},params={"",""}),各引數說明如下:
value :設定訪問地址 ,當只有value時可以省略value屬性
method:設定請求方式,常用RequestMethod.GET,RequestMethod.POST,例如:method={RequestMethod.GET}
params:設定訪問引數,例如:params={"method=hello"}
6.RequestMapping中value常用配置
value:指定請求的實際地址 (最終請求的url為:類的註解的url+方法註解的url)
value的uri值為以下兩類
6.1指定普通的具體值
@Controller @RequestMapping("/user") public class UserController{ @RequestMapping(value="/some.do") public String handleRequest() throws Exception { System.out.println("handleRequest"); return "/addsuc.jsp"; } } 該註解的是說:請求的url為”user/some.do”就會進入handleRequest方法處理。 url:user/some.do
|
6.2指定為含有某變數的一類值(restful風格)
@RequestMapping(value="/{userId}/delete.do",method=RequestMethod.GET) public String delete(@PathVariable String userId){ System.out.println("delete:"+userId); return "success.jsp"; } 這個註解:url中帶了引數userId url:user/123/delete.do 使用@PathVariable 指定形參接收url中的資料 |
7.引數繫結
頁面表單如下
<form action="user/addUser.do" method="post"> 使用者名稱:<input type="text" name="name"/><br/> 年齡:<input type="text" name="age"/><br/> 生日:<input type="text" name="birth"/><br/> <input type="submit" value="新增"/> </form> |
7.1. request接收前臺引數
@RequestMapping(value="/addUser.do",method=RequestMethod.POST) public String addUser(Model model,HttpServletRequest request){ String name = request.getParameter("name"); String age = request.getParameter("age"); String birth = request.getParameter("birth"); System.out.println("姓名"+name); System.out.println("年齡"+age); System.out.println("生日"+birth); return "addsuc.jsp"; } |
注意:日期的格式必須是 1988/10/10
7.1. 直接使用形參獲取前臺傳遞的引數資料
@RequestMapping(value="/addUser.do",method=RequestMethod.POST) public String addUser(String name,Integer age,Date birth){ System.out.println("姓名"+name); System.out.println("年齡"+age); System.out.println("生日"+birth); return "addsuc.jsp"; } |
7.2. 使用物件接受前臺傳遞的引數
public class User { private String name; private Integer age; private Date birth; public User(String name, Integer age, Date birth) { this.name = name; this.age = age; this.birth = birth; } } |
@RequestMapping(value="/addUser.do",method=RequestMethod.POST) public String addUser(User user){ System.out.println("姓名"+ user.getName()); System.out.println("年齡"+ user.getAge()); System.out.println("生日"+ user.getBirth()); return "addsuc.jsp"; } |
8.頁面跳轉
Controller跳轉方式:主要通過方法的型別來進行跳轉,主要返回型別有
1、String
2、ModleAndView
3、void
4、json
8.1.String
請求轉發
重定向
8.2. ModleAndView
@RequestMapping(value="/addUser.do",method=RequestMethod.POST) public ModelAndView addUser(ModelAndView mv,User user){ System.out.println("姓名"+ user.getName()); System.out.println("年齡"+ user.getAge()); System.out.println("生日"+ user.getBirth()); mv.addObject("name", user.getName()); mv.setViewName("/addsuc.jsp"); return mv; } |
8.3.void
@RequestMapping(value="/addUser.do",method=RequestMethod.POST) public void addUser(User user,HttpServletRequest request,HttpServletResponse response) throws Exception{ System.out.println("姓名"+ user.getName()); System.out.println("年齡"+ user.getAge()); System.out.println("生日"+ user.getBirth()); request.setAttribute("name", user.getName()); request.getRequestDispatcher("/addsuc.jsp").forward(request, response); } |
9.資料回顯
1.HttpServletRequest HttpSession
2.ModleAndView
3.Model
4.json
1.匯入jar包
commons-beanutils.jar
commons-collections.jar
commons-lang.jar
ezmorph-1.0.2.jar
commons-logging-1.1.jar
json-lib-2.4-jdk13.jar
2.編寫jsp
<html> <head> <base href="<%=basePath%>"> <title>My JSP 'JsonJquery.jsp' starting page</title> <script type="text/javascript" src="./js/jquery-1.8.3.js" ></script> <script type="text/javascript"> $(document).ready(function() { $("#btn").click(function(){ $.ajax({ url:"getJson.do", data:{username:"12",date:new Date()}, type:"get", dataType:"json", success: function(result){ $.each(result, function(index, item){ $("#show").html($("#show").html()+ "<option value="+item+">"+item+"</option>"); }); } }); }); }); </script> </head>
<body> <button id="btn">獲取json資料</button> <select id="show"> </select> </body> </html> |
3.編寫Controller
@Controller public class JsonController { @RequestMapping(value="/getJson.do") public void getJson(HttpServletResponse response,String username){ response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); PrintWriter out; try { out = response.getWriter(); List<String> list = new ArrayList<String>(); list.add("義大利"); list.add("韓國"); JSONArray jsonArray = new net.sf.json.JSONArray(); //通過json外掛生成json字串傳向前臺 JSONArray array = jsonArray.fromObject(list); out.print(array); //手動拼接json字串方式向前臺傳參 //String json="[{\"name\":\"中國\"},{\"name\":\"美國\"}]"; //out.print(json); out.flush(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
注:生成json的jar包有很多,只要保證返回的是json資料就可以
10.將jsp放在WEB-INF下
對於外部訪問來說,WEB-INF下的檔案都是不可見的(即不能通過url獲得WEB-INF下的任何檔案),所以直接訪問jsp是不可能的。WEB-INF的存在以及其下的lib和classes目錄的作用都是jsp規定的,主要是系統執行的配置資訊和環境,用來儲存服務端配置檔案資訊和在服務端執行的類檔案,它下面的東西不允許客戶端直接訪問的,這是jsp環境的規定。將jsp存放在WEB-INF後,只可以從伺服器內部通過請求轉發的方式訪問
11.檢視解析器
在spring-servlet.xml中新增如下配置
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 檢視字尾,controller中的方法返回的url字串會新增該字尾 --> <property name="suffix" value=".jsp"/> <!-- 檢視字首controller中的方法返回的url字串會新增該字首 --> <property name="prefix" value="/WEB-INF/jsp/"/> </bean> |
return "addsuc"; 實際跳轉的url為:/WEB-INF/jsp/addsuc.jsp
12.檔案上傳下載
1.新增jar包
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
2. 在spring-servlet.xml配置處理檔案上傳的bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8" /> <!-- 預設編碼 (ISO-8859-1) --> <property name="maxInMemorySize" value="10240" /> <!-- 最大記憶體大小 (10240) 設定在檔案上傳時允許寫到記憶體中的最大值--> <property name="uploadTempDir" value="/temp/" /> <!--(臨時檔案儲存目錄) 上傳後的目錄--> <property name="maxUploadSize" value="-1" /> <!-- 最大檔案大小,-1為無限止(-1) --> </bean>
|
12.1.單個檔案上傳
@RequestMapping(value="/upload.do",method=RequestMethod.POST) public String fileUpLoad(String name,@RequestParam("file") CommonsMultipartFile file,HttpSession session){ if(!file.isEmpty()){ String path = session.getServletContext().getRealPath("/upload/"); String fileName = file.getOriginalFilename(); String fileType = fileName.substring(fileName.lastIndexOf(".")); File targetFile = new File(path,new Date().getTime()+fileType); try { file.getFileItem().write(targetFile); } catch (Exception e) { e.printStackTrace(); } } return "showData"; } 編寫jsp頁面 <form action="upload.do" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="submit" value="上傳"> </form> |
12.2.上傳多個檔案
@RequestMapping(value="/mupload.do",method=RequestMethod.POST) public String muFileUpLoad(String name,@RequestParam("file") CommonsMultipartFile[] files,HttpSession session){ if(files!=null && files.length>0){ String path = session.getServletContext().getRealPath("/upload/"); for (CommonsMultipartFile file : files) { String fileName = file.getOriginalFilename(); String fileType = fileName.substring(fileName.lastIndexOf(".")); File targetFile = new File(path,new Date().getTime()+fileType); try { file.getFileItem().write(targetFile); } catch (Exception e) { e.printStackTrace(); } } } return "showData"; } 編寫jsp頁面 <form action="mupload.do" method="post" enctype="multipart/form-data"> <input type="file" name="file" /> <input type="file" name="file" /> <input type="submit" value="上傳"> </form> |
12.3.檔案下載
@RequestMapping(value="/downLoad.do",method=RequestMethod.GET) public void downLoad(HttpSession session,HttpServletResponse response,String fileName)throws Exception{ String path = session.getServletContext().getRealPath("/upload")+"\\"+fileName; File file = new File(path); if(!file.exists()){ response.sendError(404, "您要下載的檔案沒找到"); return; } BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); response.setContentType("multipart/form-data"); /** * 服務端向客戶端遊覽器傳送檔案時,如果是瀏覽器支援的檔案型別,一般會預設使用瀏覽器開啟,比如txt、 jpg等,會直接在瀏覽器中顯示,如果需要提示使用者儲存,就要利用Content-Disposition進行一下處理, * 關鍵在於一定要加上attachment: */ response.setHeader("Content-Disposition", "attachment;filename="+fileName); OutputStream out = response.getOutputStream(); byte [] buff = new byte[1024]; int len = -1; while((len= bis.read(buff))!=-1){ out.write(buff,0,len); } bis.close(); out.close(); } |