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>测试1title>
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>测试2title>
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的配置


<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 Configurationdescription>

    <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/这样是不行的,它会报错说找不到文件。

你可能感兴趣的:(Spring)