Spring表單提交和頁面數據顯示的請求處理大致過程

首先在web.xml加上

<web-app>
    <servlet>
      <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
  • DispatcherServlet是Spring Web MVC框架的核心,名字爲springServlet的DispatcherServlet會攔截所有以/開頭的請求,並進行處理
  • 每個DispatcherServlet都有自己的WebApplicationContext
  • 在DispatcherServlet初始的過程中,Spring會在web應用的WEB-INF文件下尋找名字爲 [servlet-name]-servlet.xml 的配置文件,該文件中聲明瞭你在Spring Web MVC框架中所有所使用的bean,和配置
  • 你可以通過servlet的初始化參數來改變該文件的路徑,就像上面的那樣,它會去classpath下面找spring-mvc.xml配置文件來初始化

實體類

package com.modules.entity;

public class User {

    private Integer id;

    public SiteUser(Integer id){
        this.id = id;
    }

    public SiteUser(){

    }

    @Override
    public String toString(){
        return "User" + id;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

控制器

package com.modules.web;

@Controller
@RequestMapping(value="${adminPath}/user")
public class UserController{

    @ModelAttribute("myUser")
    public SiteUser get(@RequestParam(required=false) String id){
        System.out.println("Get id" + id);
        return new User(Integer.valueOf(id));
    }

    @RequestMapping(value="form")
    public String form(@ModelAttribute("myUser") User user, Model model){
        model.addAttribute("error", "getError");
        for (String name : model.asMap().keySet()){
            System.out.println(name);
        }
        System.out.println("get" + user);
        return "userForm";
    }

    @RequestMapping(value="into")
    public String into(@ModelAttribute("myUser") User user, Model model){
        model.addAttribute("error1", "getError1");
        System.out.println("get" + user);
        return "userForm";
    }
}

1.@RequestMapping(value=”${adminPath}/user”)這句話就是映射的請求的路徑,相當於將配置文件properties文件裏面的值拿出來,相當於/admin/user,adminPath爲key,他會將匹配的路徑統一交給該處理器處理
2.@ModelAttribute(“myUser”),相當於給get方法的返回值起了一個名字放入Model對象中(map),key爲myUser,value爲返回值。每次交給處理器處理的時候都會先執行get方法。
3.你可以看到into和form方法都有用上@ModelAttribute(“myUser”),因爲如果不加上執行該方法的時候它會默認在Model對象裏面尋找key爲user沒有就自己new出一個,這個時候如果沒有在User實體類裏面加上無參構造函數就會報錯。
4.兩個方法都有字符串返回值,這就是返回你需要用數據渲染的視圖的路徑,而Model對象也會隨之字符串一起返回,這樣你就可以在頁面時使用
5.在form方法裏面我遍歷了Model對象的key,裏面會輸出下面的結果,這樣就可以證明我上面的結論

org.springframework.validation.BindingResult.myUser
error

6.get方法的參數爲id並在旁邊加上@RequestParam,意味着這是一個請求參數key爲id,false表示即便是null也行

表單1

將第一個表單起名字爲userForm.jsp,放在WebRoot下面

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="ctx" value="${pageContext.request.contextPath}/admin"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>測試1</title>
</head>
<body>
    <form:form action="${ctx}/user/into" method="post">
        <input type="text" name="id"/><br/>
        <input type="submit" value="保 存"/>
    </form:form>
</body>
</html>
  1. 在這個表單中,因爲沒有名爲myUser的對象所以不能綁定modelAttribute屬性,如果綁定就會報錯Neither BindingResult nor plain target object for bean name ‘myUser’ available as request attribute
  2. 也就是你在跳轉到該表單的時候在Controller裏面需要返回一個User對象名字爲myUser才能綁定到form:form標籤的modelAttribute屬性上

表單2

第二個表單我在WEB-INF下面的views文件夾裏面名字同樣叫做userForm.jsp

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="ctx" value="${pageContext.request.contextPath}/admin"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>測試2</title>
</head>
<body>
    <form:form modelAttribute="myUser" action="${ctx}/user/form" method="post">
        <form:input path="id"/><br/>
        <input type="submit" value="保 存"/>
    </form:form>
    ${myUser.id}----------<br/>
    ${error1}<br/>
</body>
</html>

1.你可以看到只有後面的表單都有綁定一個myUser,而myUser正好就是後臺User對象的名字,第一次從控制器返回的時候,自動將User對象給綁定到頁面元素了
2.這個時候,如果你將UserController中的get方法改爲下面的樣子(前提是你的User要有無參的構造方法),你會發現id自動幫你set進去了(前提是你的User裏面要有get和set方法,否則會報錯javax.el.PropertyNotFoundException: Property ‘id’ not found on type com.modules.entity.User
)
3.modelAttribute作用:我猜想是因爲java對象User和表單元素映射(綁定),而User的id和path爲id的相對應,所以我們就可以將該對象顯示到頁面上去(比如你想要修改客戶信息,它可以將客戶信息顯示出來當然你要使用spring的標籤)

@ModelAttribute("myUser")
public User get(){
    return new User();
}

大致的訪問流程

  1. 我先訪問http://localhost:8080/test/userForm.jsp然後輸入數據假設是11
  2. 點擊保存之後你會發送一個請求http://localhost:8080/test/admin/user/into,接下來DispatcherServlet會攔截你的請求,並委託請求給對應的處理器因爲和UserController的映射路徑相匹配所以就給了它
  3. 接着先執行了get方法接收了表單提交過來的的id參數輸出下面的結果,然後返回一個User,id爲11,放入Model對象裏面,起名爲myUser
Get id11
  1. 因爲將into方法映射在路徑into上面所以執行into方法,它會自動將model裏面key爲myUser和model對象傳入。在裏面加上error1,再次控制檯上輸出getUser11,返回視圖路徑。而在網頁上的URL就是http://localhost:8080/test/admin/user/into
  2. 通過顯示數據,可以知道控制器將model(模型數據)和視圖路徑返回給DispatcherServlet(Model對象和視圖名都放在ModelAndView對象中),然後再將其用來尋找並渲染視圖。(值得注意的是在form:input標籤中有11的值)
11----------
getError1

6.在文本框裏面輸入22,點擊保存發送請求http://localhost:8080/test/admin/user/form,同樣和上面過程一樣,將model對象裏面的key全部輸出,你會發現原來是error1現在沒了說明model已經不是同一個了

org.springframework.validation.BindingResult.myUser
error
getUser22

7.頁面上的結果就是,可以看到沒有顯示error1的值,說明這個值不存在

22----------

配置文件

最後是spring-mvc.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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

    <description>Spring MVC Configuration</description>

    <context:property-placeholder location="classpath:my.properties" />

    <context:component-scan base-package="com" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="${prefix}"/>
        <property name="suffix" value="${suffix}"/>
    </bean>

</beans>
  1. 加載屬性配置文件,因爲你控制器的映射路徑就需要裏面的值
  2. 掃描@Controller,就不用說了,不註冊爲bean,你怎麼知道這個控制器?
  3. mvc:annotation-driven,這個你要是不加上,@RequestMapping就沒什麼用了
  4. InternalResourceViewResolver視圖資源解析,上面的配置表示,將在控制器返回的ModelAndView的基礎上,加上目錄前綴/WEB-INF/views/,加後文件名稱後綴.jsp,這樣就能訪問/WEB-INF/下的文件。如果你是直接URL上自己打上/WEB-INF/這樣是不行的,它會報錯說找不到文件。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章