SpringMVC學習筆記_01

一、JAVAEE體系結構

  • JAVAEE體系結構圖以下所示:

二、什麼是springmvc?

  • 什麼是mvc?
    • Model1
    • Model2
  • SpringMVC是什麼?
    • SpringMVC是一個web層mvc框架,相似struts2。
  • SpringMVC和Spring?
    • Springmvc是Spring的組成部分。
  • SpringMVC執行流程(運行原理)
    • 回憶Struts2執行流程:
      • 前端控制器:StrutsPrepareAndExcuteFilter攔截請求(控制層):攔截請求,轉發請求
      • 尋找Action執行,處理請求數據
      • ActionMapping去尋找執行類Action --> UserAction
      • 找到ActionProxy:StrutsActionProxy extends DefaultActionProxy
      • 經過代理類ActionProxy根據struts.xml尋找到真正的執行類Action
    • SpringMVC執行流程(運行原理),以下圖所示:

三、springmvc第一個程序案例

3.一、不使用jsp視圖解析器+使用jsp視圖解析器

(1)使用eclipse,建立一個動態的web工程
  其中Dynamic web module version版本選擇 2.5,這樣兼容性好一些;
  Default output folder設置爲 WebRoot\WEB-INF\classes
  Content directory設置爲 WebRoot
  更改JRE System Library[J2SE-1.5]爲 JRE System Library[jre1.7.0_80]
  刪掉沒用的庫:EAR Libraries
  增長服務器運行環境庫 Server Runtime,否則jsp文件會報錯。javascript


  建立完項目後,將整個項目的編碼改成UTF-8。
  操做步驟:選中項目右鍵 --> Properties --> Resource --> Text file encoding --> Other中選擇UTF-8。html

  對於動態的java web項目,爲了工程目錄結構的清爽,咱們將引入的jar包放到「Web App Libraries」中,能夠經過「小三角」選擇是否「Show 'Referenced Libraries' Node 」進行調節。
  對於普通的java項目,爲了工程目錄結構的清爽,咱們將引入的jar包放到「Referenced Libraries」中,能夠經過「小三角」選擇是否「Show 'Referenced Libraries' Node 」進行調節。前端

(2)導入springmvc的jar包
  本案例共16個jar,以下圖所示:java

(3)在web.xml配置前端控制器:DispatcherServlet(入口)jquery

    <!-- 配置前端控制器:DispatcherServlet -->
    <servlet >
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

  咱們還須要配置springmvc.xml文件的初始化參數,以下圖所示:web

(4)配置springmvc.xml
  參考文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.htmlajax

<?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"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    <!-- 配置處理器映射器,springmvc默認的處理器映射器 -->
    <!-- BeanNameUrlHandlerMapping:根據bean(自定義的Controller)的name屬性的url去尋找執行類Handler(Action)即Controller -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

    <!-- 配置處理器適配器,負責執行Controller,也是springmvc默認的處理器適配器 -->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置自定義的Controller:UserController -->
    <bean name="/hello.do" class="com.itheima.controller.UserController"></bean>

    <!-- 配置jsp視圖解析器,InternalResourceViewResolver負責解析出真正的邏輯視圖 -->
    <!-- 後臺返回邏輯視圖:index,jsp視圖解析器解析出真正的物理視圖:前綴+邏輯視圖+後綴 ==>/WEB-INF/jsps/index.jsp -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsps/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

(5)自定義Controller(至關於Struts2裏面的Action)spring

public class UserController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 接收請求,接收參數,驗證參數,處理請求
        // 封裝參數,調用業務方法,返回處理結果數據ModelAndView

        // 演示案例中咱們只模擬下而已:向前臺返回數據
        ModelAndView mv = new ModelAndView();
        mv.addObject("hello", "like xiaoyi");

        // 指定跳轉的視圖
        // 返回真實的物理視圖,省略了八、9步
        // mv.setViewName("/WEB-INF/jsps/index.jsp");
        // 返回邏輯視圖
        mv.setViewName("index");

        return mv;
    }
}

(6)定義視圖頁面
  根據視圖解析路徑:WEB-INF/jsps/index.jsp數據庫

<body>
    <h1>${hello}</h1>
</body>

(7)瀏覽器訪問
  訪問地址:http://localhost:8080/day63_SpringMVC_01/hello.dojson

四、根據程序分析springmvc執行流程(畫圖)

  • 該圖同SpringMVC執行流程圖(運行原理)

五、處理器映射器

5.一、配置默認處理器映射器(BeanNameUrlHandlerMapping)

功能:尋找Controller
   根據url請求去匹配bean的name屬性url,從而獲取Controller

5.二、配置集中處理器映射器(SimpleHandlerMapping)

功能:尋找Controller
   根據瀏覽器url匹配簡單url的key,key經過Controller的id找到Controller

5.三、配置類名處理器映射器(ClassNameHandlerMapping)

功能:尋找Controller
   直接根據類名(UserController),類名.do來訪問,類名首字母小寫

  • 3個處理器映射器能夠共存。都可以訪問成功。

六、處理器適配器

6.一、配置默認處理器適配器(SimpleControllerHandlerAdapt)

功能:執行Controller
   負責執行實現了Controller接口的後端控制器,例如:UserController,調用Controller裏面的方法,返回ModelAndView。


默認處理器適配器源碼分析,以下圖所示:

6.二、配置請求處理器適配器(HttpRequestHandlerAdapter)

功能:執行Controller
   負責執行實現了HttpRequestHandler接口的後端控制器。


演示過程:
  自定義實現了接口HttpRequestHandler的實現類HttpController,以下圖所示:

  在springmvc.xml中配置自定義的bean,即自定義的HttpController,以下圖所示:

   上面的這種方式無限接近servlet的開發。
  • 2個處理器適配器能夠共存。

七、命令控制器

7.一、Controller簡介

一、收集、驗證請求參數並綁定到命令對象;
二、將命令對象交給業務對象,由業務對象處理並返回模型數據;
三、返回ModelAndView(Model部分是業務對象返回的模型數據,視圖部分是邏輯視圖名)。

  • 普通控制器(繼承接口Controller,繼承接口HttpRequestHandler)
  • 命令控制器(繼承抽象類AbstractCommandController)
    • 例子:跳轉到添加頁面,進行頁面跳轉,參數提交get請求或者post請求
  • 參數控制器(類ParameterizableViewController)

Springmvc經過命令設計模式接受頁面參數。

7.二、演示:自定義命令控制器

示例以下:
(1)自定義命令控制器

package com.itheima.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;

import com.itheima.domain.User;

// 從頁面接收參數,封裝到JavaBean中,本例中的JavaBean是User
@SuppressWarnings("deprecation")
public class CommandController extends AbstractCommandController {

    // 指定把頁面傳過來的參數封裝到對象,使用命令設計模式
    public CommandController() {
        this.setCommandClass(User.class);
    }

    @Override
    protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command,
            BindException errors) throws Exception {
        // 參數被封裝進命令對象,這個過程很複雜,咱們暫時不用管它,只要知道它使用的是命令設計模式便可

        // 把命令對象強轉成User對象
        User user = (User) command;
        // 設置Model的數據,值能夠是任意pojo
        ModelAndView mv = new ModelAndView();
        mv.addObject("user", user);
        // 指定返回頁面
        mv.setViewName("index");

        return mv;
    }
}

(2)定義javaBean

package com.itheima.domain;

import java.util.Date;

public class User {

    private Integer id;
    private String username;
    private String age;
    private Date birthday;
    private String address;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
}

(3)封裝參數頁面
  文件位置:/day63_SpringMVC_01/WebRoot/WEB-INF/jsps/add.jsp
add.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/command.do" method="post">
        姓名:<input type="text" name="username" id="username"><br>
        年齡:<input type="text" name="age" id="age"><br>
        生日:<input type="text" name="birthday" id="birthday"><br>
        地址:<input type="text" name="address" id="address"><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>

(4)獲取參數頁面
  文件位置:/day63_SpringMVC_01/WebRoot/WEB-INF/jsps/index.jsp
index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>${user.username}---${user.age}---${user.birthday}---${user.address}</h1>
</body>
</html>

(5)跳轉到add頁面
  因爲add頁面在WEB-INF下面不能直接訪問,須要經過Controller來訪問。

package com.itheima.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class ToAddController implements Controller {

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 跳轉到add頁面
        ModelAndView mv = new ModelAndView();
        mv.setViewName("add");

        return mv;
    }
}

(6)在springmvc.xml中配置bean

    <!-- 配置自定義的CommandController:CommandController -->
    <bean name="/command.do" class="com.itheima.controller.CommandController"></bean>

    <!-- 配置自定義的ToAddController:ToAddController -->
    <bean name="/toAdd.do" class="com.itheima.controller.ToAddController"></bean>

7.三、中文亂碼解決

(1)解決get請求亂碼
  配置tomcat的編碼,以下圖所示:


(2)解決post請求亂碼
  在web.xml中,配置spring編碼過濾器,以下所示:
    <!-- 配置spring編碼過濾器 -->
    <filter>
        <filter-name>characterEcoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEcoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

7.四、時間類型轉換

  在CommandController類中重寫initBinder()方法,示例代碼以下:

// 從頁面接收參數,封裝到JavaBean中,本例中的JavaBean是User
@SuppressWarnings("deprecation")
public class CommandController extends AbstractCommandController {

    // 指定把頁面傳過來的參數封裝到對象,使用命令設計模式
    public CommandController() {
        this.setCommandClass(User.class);
    }

    @Override
    protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
        // 參數被封裝進命令對象,這個過程很複雜,咱們暫時不用管它,只要知道它使用的是命令設計模式便可

        // 把命令對象強轉成User對象
        User user = (User) command;
        // 設置Model的數據,值能夠是任意pojo
        ModelAndView mv = new ModelAndView();
        mv.addObject("user", user);
        // 指定返回頁面
        mv.setViewName("index");

        return mv;
    }

    @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        String str = request.getParameter("birthday");
        if (str.contains("/")) {
            binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy/MM/dd"), true));
        } else {
            binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
        }
    }
}

7.五、參數控制器ParameterizableViewController

  在springmvc.xml中配置參數控制器

  • 注意:使用參數控制器:不用本身定義Controller了,能夠直接使用toIndex.do進行訪問。

八、註解開發

8.一、註解開發第一個入門程序

  • 步驟以下:
    • 建立一個動態的web工程,導入jar文件
    • 配置web.xml
    • 配置springmvc.xml文件:配置處理器映射器、配置處理器適配器、配置jsp視圖解析器
    • 自定義Controller類,使用註解開發:添加,返回到成功頁面進行回顯,點擊修改回到添加頁面,初步理解參數傳遞。

(1)建立一個動態的web工程,導入jar文件
  詳細過程同三、springmvc第一個程序案例
(2)配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
    <display-name>day63_SpringMVC_01</display-name>
    <!-- 配置spring編碼過濾器 -->
    <filter>
        <filter-name>characterEcoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEcoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- 配置前端控制器:DispatcherServlet -->
    <servlet >
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 隱式默認加載springmvc.xml文件,該文件須要知足2個規範:
                命名規範:servlet-name-servlet.xml => springmvc-servlet.xml
                路徑規範:該文件必須放在WEB-INF目錄下面
        -->
        <!-- 顯示配置加載springmvc.xml文件,即配置springmvc.xml文件的初始化參數 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

(3)配置springmvc.xml文件
  配置掃描,把Controller交給spring管理、配置處理器映射器、配置處理器適配器、配置jsp視圖解析器

<?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"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd 
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
    <!-- 配置掃描,把Controller交給spring管理 -->
    <context:component-scan base-package="com.itheima"></context:component-scan>

    <!-- 配置註解的處理器映射器,做用:尋找執行類Controller -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>

    <!-- 配置註解的處理器適配器,做用:調用Controller方法,執行Controller -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>

    <!-- 配置jsp視圖解析器,InternalResourceViewResolver負責解析出真正的邏輯視圖 -->
    <!-- 後臺返回邏輯視圖:index,jsp視圖解析器解析出真正的物理視圖:前綴+邏輯視圖+後綴 ==>/WEB-INF/jsps/index.jsp -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsps/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
</beans>

(4)自定義Controller類

@Controller // 至關於<bean id="userController" class="com.itheima.controller.UserController">,即至關於建立了一個UserController對象
@RequestMapping("/user")
public class UserController {
    // 請求映射註解
    @RequestMapping("hello") // 至關於訪問/hello.do
    public String myHello() {
        // 表示springmvc返回了一個邏輯視圖hello.jsp
        return "hello";
    }
}

(5)定義hello頁面
  根據視圖解析,須要在WEB-INF下面定義jsps文件夾,在裏面定義一個hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>歡迎訪問SpringMVC</h1>
</body>
</html>

(6)訪問地址:http://localhost:8080/day63_SpringMVC_02/user/hello.do

8.二、註解開發流程圖

註解開發流程圖以下:

8.三、RequestMapping

功能:請求映射

幾種寫法:
    @RequestMapping("hello") -- 這種方式能夠匹配任何的擴展名
    @RequestMapping("/hello.do")
    @RequestMapping(value="/hello.do")
    @RequestMapping(value="/hello.do",method=RequestMethod.GET)
    @RequestMapping(value="/hello.do",method=RequestMethod.POST)
    @RequestMapping(value="/hello.do", method={RequestMethod.GET,RequestMethod.POST})

  瀏覽器直接訪問、a標籤都是get請求。
  表單提交(指定post)、ajax指定post提交。
  若是是get請求,寫成了post瀏覽器會報405錯誤,以下圖所示:

8.四、RequestMapping的根路徑

@RequestMapping("/user")
public class UserController {
    @RequestMapping("save")
    public String save() {
    }
    @RequestMapping("update")
    public String update() {
    }
    @RequestMapping("find")
    public String find() {
    }
}
訪問地址:http://localhost:8080/項目名/user/save.do

@RequestMapping("/items")
public class  ItemsController {
    @RequestMapping("save")
    public String save() {
    }
    @RequestMapping("update")
    public String update() {
    }
    @RequestMapping("find")
    public String find() {
    }
訪問地址:http://localhost:8080/項目名/items/save.do

演示:自定義根路徑

@Controller // 至關於<bean id="userController" class="com.itheima.controller.UserController">,即至關於建立了一個UserController對象
@RequestMapping("/user")
public class UserController {
    // 請求映射註解
    @RequestMapping("hello") // 至關於訪問/hello.do
    // @RequestMapping(value="/hello.do",method=RequestMethod.POST)
    public String myHello() {
        // 表示springmvc返回了一個邏輯視圖hello.jsp
        return "hello";
    }
}

訪問地址:http://localhost:8080/day63_SpringMVC_02/user/hello.do

8.五、RequestParam

  value:參數名字,即入參的請求參數名字,如value="studentid"表示請求的參數區中的名字爲studentid的參數的值將傳入。
  required:是否必須,默認是true,表示請求中必定要有相應的參數,不然將報400錯誤碼。
  defaultValue:默認值,表示若是請求中沒有同名參數時的默認值
示例以下:

public String userList(@RequestParam(defaultValue="2",value="group",required=true) String groupid) {
}
    一、形參名稱爲groupid,可是這裏使用value="group"限定參數名爲group,因此頁面傳遞參數的名必須爲group。
    二、這裏經過required=true限定groupid參數爲必需傳遞,若是不傳遞則報400錯誤,因爲使用了defaultvalue="2"默認值,即便不傳group參數它的值仍爲"2"。
    三、因此頁面不傳遞group也不會報錯,若是去掉defaultvalue="2"且定義required=true,則若是頁面不傳遞group就會報錯。

示例以下圖所示:


   @RequestParam的做用:給傳遞的參數起別名。

九、封裝參數

  • springmvc沒有成員變量,那頁面提交過來的參數該如何接收和進行傳遞呢?
  • 答:把須要傳遞的參數對象放入方法裏面,當你請求這個方法,向這個方法傳遞參數的時候,這個方法裏面的對象會自動被建立,須要的參數會自動被封裝到方法的對象裏面。

分析接受參數類型:

基本類型
    int、String等基本類型。
Pojo類型
包裝類型
集合類型

Springmvc默認支持類型:
    HttpSession、HttpRequstServlet、Model等等。

Struts2參數封裝:基於屬性驅動封裝。
Springmvc參數封裝:基於方法進行封裝。

9.一、封裝int類型參數

  • 頁面傳遞的參數都是字符串。

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveInt.do" method="post">
        ID:<input type="text" name="id" id="id"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收int類型參數 
    @RequestMapping("recieveInt")
    public String recieveInt(Integer id) {
        System.out.println(id);
        return "success";
    }
  • 特別注意:標籤input的name的屬性值id要與方法的形式參數名稱id相同。

9.二、封裝String類型參數

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveString.do" method="post">
        姓名:<input type="text" name="username" id="username"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收String類型參數 
    @RequestMapping("recieveString")
    public String recieveString(String username) {
        System.out.println(username);
        return "success";
    }

9.三、封裝數組類型參數

  • 分析:封裝數組是批量刪除時使用,使用checkbox複選框,其value屬性必須有值。

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveArray.do" method="post">
        ID:<input type="checkbox" name="ids" value="1" id="ids"><br>
        ID:<input type="checkbox" name="ids" value="2" id="ids"><br>
        ID:<input type="checkbox" name="ids" value="3" id="ids"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收數組類型參數 
    @RequestMapping("recieveArray")
    public String recieveArray(Integer[] ids) {
        System.out.println(ids);
        return "success";
    }

9.四、封裝pojo類型參數

建立一個pojo類:

public class User {

    private Integer id;
    private String username;
    private String age;
    private Date birthday;
    private String address;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", age=" + age + ", birthday=" + birthday + ", address="
                + address + "]";
    }
}

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveUser.do" method="post">
        姓名:<input type="text" name="username" id="username"><br>
        年齡:<input type="text" name="age" id="age"><br>
        生日:<input type="text" name="birthday" id="birthday"><br>
        地址:<input type="text" name="address" id="address"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收pojo類型參數 
    @RequestMapping("recieveUser")
    public String recieveString(User user) {
        System.out.println(user);
        return "success";
    }

9.四、封裝包裝類型參數

建立一個包裝類:

public class UserCustom {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveUserCustom.do" method="post">
        姓名:<input type="text" name="user.username" id="username"><br>
        年齡:<input type="text" name="user.age" id="age"><br>
        生日:<input type="text" name="user.birthday" id="birthday"><br>
        地址:<input type="text" name="user.address" id="address"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收包裝類型參數 
    @RequestMapping("recieveUserCustom")
    public String recieveUserCustom(UserCustom userCustom) {
        System.out.println(userCustom);
        return "success";
    }

9.五、封裝集合類型參數

9.5.一、封裝List集合類型參數

  • 注意:不能直接傳遞集合類型,須要把集合類型封裝到包裝類中。

咱們先把List集合封裝到包裝類中。即:在包裝類中定義List集合。提供getter和setter方法。

    private List<User> userList;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveList.do" method="post">
        姓名:<input type="text" name="userList[0].username" id="username"><br>
        年齡:<input type="text" name="userList[0].age" id="age"><br>

        姓名:<input type="text" name="userList[1].username" id="username"><br>
        年齡:<input type="text" name="userList[1].age" id="age"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收List結合類型參數 
    @RequestMapping("recieveList")
    public String recieveList(UserCustom userCustom) {
        System.out.println(userCustom);
        return "success";
    }

9.5.二、封裝Map集合類型參數

咱們先把Map集合封裝到包裝類中。即:在包裝類中定義Map集合。提供getter和setter方法。

    private Map<String, Object> maps = new HashMap<String, Object>();

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

頁面的代碼:

    <hr size="12" color="blue">
    <form action="${pageContext.request.contextPath}/user/recieveMap.do" method="post">
        姓名:<input type="text" name="mps['username']" id="username"><br>
        年齡:<input type="text" name="mps['age']" id="age"><br>
        <input type="submit" value="提交">
    </form>

接受參數的方法:

    // 接收Map結合類型參數 
    @RequestMapping("recieveMap")
    public String recieveMap(UserCustom userCustom) {
        System.out.println(userCustom);
        return "success";
    }

9.六、思考:有了struts2,爲何還須要sprigmvc呢?

  • 實現機制:
    • struts2 底層是基於`過濾器`實現的。過濾器的底層是servlet。
    • springmvc 底層基於`servlet`實現。servlet比過濾器快。
  • 運行速度:
    • struts2 是`多例`
      • 一個請求來了之後,struts2建立多少個對象?以下:
      • ActionContext、ValueStack、UserAction、ActionSuport、ModelDriven等等。
      • UserAction裏面屬性:User對象,userList集合對象等。屬於成員變量,存活時間長。
    • springmvc 是`單例`,由於是基於servlet的,servlet是單例的。
      • 一個請求來了之後,springmvc 建立多少個對象?以下:
      • Controller等等。
      • 方法的參數屬於局部變量,存活時間短。
  • 參數封裝來分析:
    • struts 基於`屬性驅動`進行封裝。
    • springmvc 基於`方法`進行封裝,粒度更細。

十、頁面回顯

  • springmvc使用Model對象進行頁面數據回顯,Model對象至關於javaweb時所學的application對象(應用域對象),因此Model對象中的數據能夠經過EL表達式進行獲取。
  • 有了Model對象,才能夠向對象中放值,那麼Model對象該如何建立呢?
    • 答:`springmvc中放到方法裏面的對象會自動被建立`,那麼咱們就把Model對象放到方法裏面。

10.一、查詢全部

頁面的代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%--引入jstl標籤 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"  prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <table border="1" style="color: blue">
        <tr>
            <td>姓名</td>
            <td>年齡</td>
            <td>生日</td>
            <td>地址</td>
            <td>操做</td>
        <tr/>
        <c:forEach items="${userList}" var="user">
            <tr>
                <td>${user.username}</td>
                <td>${user.age}</td>
                <td>${user.birthday}</td>
                <td>${user.address}</td>
                <td>
                    <href="${pageContext.request.contextPath}/user/updateById.do?id${user.id}">修改</a>
                </td>
            <tr/>        
        </c:forEach>
    </table>
</body>
</html>

接受參數的方法:

    // 查詢全部
    @RequestMapping("listAll")
    public String listAll(Model model) {
        // 因爲演示咱們沒有查詢數據庫,因此下面咱們模擬幾條數據
        List<User> userList = new ArrayList<User>();

        User user1 = new User();
        user1.setId(1);
        user1.setUsername("曉藝");
        user1.setAge("26");
        user1.setAddress("物資學院");
        user1.setBirthday(new Date());

        User user2 = new User();
        user2.setId(2);
        user2.setUsername("黑澤");
        user2.setAge("26");
        user2.setAddress("青年路");
        user2.setBirthday(new Date());

        User user3 = new User();
        user3.setId(3);
        user3.setUsername("奇遇");
        user3.setAge("28");
        user3.setAddress("物資學院");
        user3.setBirthday(new Date());

        userList.add(user1);
        userList.add(user2);
        userList.add(user3);

        // Model至關於application域對象
        model.addAttribute("userList", userList);

        return "list";  
    }

瀏覽器顯示效果:

十一、URL模版映射

  • URL模版映射主要是爲了實現請求Restfull軟件架構設計模式
  • Restfull軟件架構設計模式使得請求更簡潔、更安全,方便於搜索引擎收錄。

11.一、普通模式修改

頁面的代碼:

    <td>
        <href="${pageContext.request.contextPath}/user/updateByIdNormal.do?id=${user.id}">修改</a>
    </td>

接受參數的方法:

    // 普通模式修改
    @RequestMapping("updateByIdNormal")
    public String updateByIdNormal(Integer id) {
        System.out.println(id);
        return "redirect:listAll.do";
    }

訪問的地址爲:http://localhost:8080/day63_SpringMVC_02/user/updateByIdNormal.do?id=1

11.二、Restfull風格設計模式修改

(1)初始Restfull風格設計模式修改
頁面的代碼:

    <td>
        <href="${pageContext.request.contextPath}/user/updateByIdRestfull/${user.id}.do">修改</a> <!-- 把參數放在了請求的裏面了 -->
    </td>

接受參數的方法:

    // 初始Restfull模式修改
    @RequestMapping("updateByIdRestfull/{id}")
    public String updateByIdRestfull(@PathVariable Integer id) {
        System.out.println(id);
        return "redirect:/user/listAll.do"; // 請求重定向
    }

訪問的地址爲:http://localhost:8080/day63_SpringMVC_02/user/updateByIdRestfull/1.do

(2)最終Restfull風格設計模式修改
  約定:在web.xml配置攔截方式:在rest目錄下全部請求都被攔截,servlet能夠攔截目錄。
web.xml中配置代碼以下:

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

頁面的代碼:

    <td>
        <href="${pageContext.request.contextPath}/rest/user/updateByIdRestfull/${user.id}">修改</a> 
    </td>

接受參數的方法:

    // 最終Restfull模式修改
    @RequestMapping("updateByIdRestfull/{id}")
    public String updateByIdRestfull(@PathVariable Integer id) {
        System.out.println(id);
        return "redirect:/user/listAll.do"; // 請求重定向
    }

訪問的地址爲:http://localhost:8080/day63_SpringMVC_02/rest/user/updateByIdRestfull/1
其中:
  {id}:表示匹配接受頁面url路徑中的參數
  @PathVariable:表示{id}裏面參數注入後面參數id裏面
  url模版映射須要@RequestMapping和@PathVariable結合使用。
畫圖理解URL模版映射,以下圖所示:

11.三、在線安裝eclipse提示插件--Spring tools suite

步驟:Help --> Eclipse Marketplace… --> 在Find中輸入Spring tools suite,點擊安裝便可。
安裝成功後的截圖以下:

 

十二、轉發和重定向

12.一、轉發

  • 本類中進行轉發:本類中方法與方法之間進行forward
    • 關鍵字:forward
    • 轉發方式一:return "forward:listAll.do";
    • 轉發方式二:return "/user/forward:listAll.do";
    • 注意:`user根路徑前面必須有/。`
  • 跨類進行轉發:
    • 轉發方式:return "forward:/items/listAll.do";

測試代碼以下:

    // 測試forward
    @RequestMapping("forward")
    public String forward() {
        // return "forward:listAll.do"; // 本類中轉發方式一
        // return "/user/forward:listAll.do"; // 本類中轉發方式二
        return "forward:/items/listAll.do"; // 跨類進行轉發
    }

12.二、重定向

  • 本類中進行重定向:本類中方法與方法之間進行redirect
    • 關鍵字:redirect
    • 重定向方式一:return "redirect:listAll.do";
    • 重定向方式二:return "redirect:/user/listAll.do";
  • 跨類進行重定向:
    • 重定向方式:return "redirect:/items/listAll.do";

測試代碼以下:

    // 測試redirect
    @RequestMapping("redirect")
    public String redirect() {
        // return "redirect:listAll.do"; // 本類中重定向方式一
        // return "/user/redirect:listAll.do"; // 本類中重定向方式二
        return "redirect:/items/listAll.do"; // 跨類進行重定向
    }
 

1三、標籤< mvc:annotation-driven />的使用

詳解以下:

標籤<mvc:annotation-driven /> 表示默認建立處理器映射器RequestMappingHandlerMapping、處理器映射器RequestMappingHandlerAdapter,還表示默認啓動json格式數據的支持。

因此在springmvc.xml中就不要再配置處理器映射器和處理器映射器了。
只須要配置這一句就能夠了。
 

1四、RequestBody 和 ResponseBody

  • @RequestBody 和 @ResponseBody,這兩個註解主要是爲了提供對json格式數據的支持。
  • @RequestBody的做用:把前臺頁面請求的json格式數據直接封裝成JavaBean,使用ajax進行數據傳遞。
  • @ResponseBody的做用:在後臺,把JavaBean強制轉換成json格式數據返回給前臺頁面。

這兩個註解不能直接使用,須要依賴兩個Jackson的jar包。

(1)先導入Jackson的jar包


(2)在springmvc.xml中配置json格式轉換
注意:咱們也能夠直接使用 <mvc:annotation-driven />,由於該標籤默認啓動json格式數據的支持。
    <!-- 配置註解的處理器適配器,做用:調用Controller方法,執行Controller -->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <!-- 配置對json格式數據的支持 -->
        <property name="messageConverters">
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
        </property>
    </bean> 

(3)請求json格式數據,返回json格式數據
(4)請求pojo格式數據,返回json格式數據
/day63_SpringMVC_02/WebRoot/WEB-INF/jsps/requestjson.jsp
前臺代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<!-- 引入jquery.js的支持 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.js"></script>
</head>
<body>
    <input type="button" value="請求是json格式數據,返回是json格式數據" onclick="requestJson();">
    <br>
    <input type="button" value="請求是pojo格式數據,返回是json格式數據" onclick="requestPojo();">
    <script type="text/javascript">
        function requestJson() {
            // 演示:構造一個json格式數據
            var jsonObj = JSON.stringify({'username':'曉藝','age':'26','address':'物資學院'}); // stringify的做用:把json格式的數據數強轉成json對象
            // 發送ajax請求
            $.ajax({
                type:'post',
                url:'${pageContext.request.contextPath}/user/requestJson.do',
                contentType:'application/json;charset=UTF-8', // 默認: "application/x-www-form-urlencoded"
                data:jsonObj,
                success:function(data) { // 回調函數
                    alert(data);
                }
            });
        }
        function requestPojo() {
            // 演示:構造一個pojo格式數據
            var pojoObj = 'username=黑澤&age=26&address=青年路';
            // 發送ajax請求
            $.ajax({
                type:'post',
                url:'${pageContext.request.contextPath}/user/requestPojo.do',
                data:pojoObj,
                success:function(data) { // 回調函數
                    alert(data);
                }
            });         
        }
    </script>
</body>
</html>

後臺代碼:

    // 跳轉方法,跳轉到requestjson.jsp頁面
    @RequestMapping("toJson")
    public String tiJson() {
        return "requestjson";
    }

    // 接收json格式數據,使用 @RequestBody 把json格式數據封裝進JavaBean對象中(本例中是User對象)
    // 返回json對象,使用 @ResponseBody 把User對象轉換成json對象
    @RequestMapping("requestJson")
    public @ResponseBody User requestJson(@RequestBody User user) {
        System.out.println(user);

        return user;
    }

    // 接收pojo格式數據
    // 返回json對象,使用@ResponseBody 把User對象轉換成json對象
    @RequestMapping("requestPojo")
    public @ResponseBody User requestPojo(User user) {
        System.out.println(user);

        return user;    }
相關文章
相關標籤/搜索