spring MVC 之controller (一)

来源:互联网 发布:阿里云服务器托管 编辑:程序博客网 时间:2024/06/06 05:05

在spring MVC 中,每个请求到DispatcherServlet后根据需求,将会分配到相对应的控制器controller去处理,因此controller在 spring MVC中的作用是非常重要的。本文先介绍两类controller。

一、页面直接跳转

当我们请求一个页面时,由于文件都隐藏在了文件下,无法直接访问,因此需要有一个控制器来实现简单的页面跳转,跳转到对应的页面。这类控制器不需要对请求做太多的处理地,只需实现页面跳转即可。这时,我们可以不需要自己去设计自己的controller,而是直接配置现有的controller类。与页面直接跳转的现有controller主要有以下两个:

1、ParameterizableViewController

我们在“/WEB-INF/jsp/”目录下创建了一个welcome.html文档,为了实现在浏览器中输入welcome.test就直接跳转到welcome.html,spring-servlet.xml文件配置主要如下:

这里写图片描述

不需要自己写控制器,而是直接调用现有的ParameterizableViewController类来实现。只需要指定对应的视图名就可以。然后就能根据视图解析器去查找需要跳转的页面,视图解析器设置如下:

<!-- 视图解析器 -->    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>        <!-- 前缀 -->        <property name="prefix" value="/WEB-INF/jsp/" />        <!-- 后缀 -->        <property name="suffix" value=".html" />    </bean>

2、UrlFilenameViewController

这个控制器相对于ParameterizableViewController更为简洁,可以不用指明视图名,而直接通过请求的url去查找文件,直接以请求 的URL来确定视图名,然后直接跳转过去。例如请求的url是“welcome.test”,那么从中提取出视图名为“welcome”,而不需要另外指定视图名。这种方法适用于请求的url跟视图名一致。

这里写图片描述

这两种方法都是直接配置现有的controller类来实现页面的直接跳转,区别在于ParameterizableViewController类可以根据需要指定视图名,较为灵活,而UrlFilenameViewController类只能跳转到跟url对应的视图名,而不能自行指定视图名。

welcome.html文档如下:

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>welcome page</title></head><body>    <h1>this is the welcome page</h1></body></html>

启动服务器后,在外部浏览器中输入:http://localhost:8080/springMVC/welcome.test,即可正常跳转到welcome.htm页面。

这里写图片描述

二、封装表单参数的控制器

一般我们在进行表单登记或者注册时,会要求填较多的信息,这些信息如果按照之前介绍的继承Controller来实现参数的注入,当表单参数较多时,代码就会显得冗余。因此我们希望controller能实现数据的自动封装。这里,我将介绍两种方法来实现表单参数的自动封装。

1、AbstractCommandController

首先需要注意的一个问题是由于AbstractCommandController在spring 3之后就不建议使用了,因此在一些比较新的spring MVC框架中并不包含这个类,这里本着学习的态度,还是了解一下。所以在导入jar包是需要注意版本问题。通过查看各版本的jar包,注意到3.2.2这个版本中包含有AbstractCommandController,读者们可以到 http://repo.spring.io/libs-release-local/org/springframework/spring/3.2.2.RELEASE/ 中下载。在测试中,我导入的jar包如下:

这里写图片描述

接下来使配置文件,首先配置info.javainfoController.java文档

这里写图片描述

infoController.java文档

package test.springMVC;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;@SuppressWarnings("deprecation")public class infoController extends AbstractCommandController {    @Override    protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException exception)            throws Exception {        info inf = (info)command;        System.out.println(inf);        return new ModelAndView("addsucc");    }}

info.java文档

package test.springMVC;public class info {    private String name;    private int num;    private String phone;    public String getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getNum() {        return num;    }    public void setNum(int num) {        this.num = num;    }    public String toString() {        return name + ";" + num + ";" + phone;    }}

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: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.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">                        <!-- 设置映射方式 -->    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">        <property name="mappings">            <props>                <prop key="addInfo.html">addInfoController</prop>                <prop key="add.test">addSuccController</prop>            </props>        </property>    </bean>    <bean id="addInfoController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController">    </bean>    <bean id="addSuccController" class="test.springMVC.infoController">        <property name="commandClass" value="test.springMVC.info"></property>    </bean>    <!-- scan the package and the sub package -->    <context:component-scan base-package="test.SpringMVC" />    <!-- don't handle the static resource -->    <mvc:default-servlet-handler />    <!-- if you use annotation you must configure following setting -->    <mvc:annotation-driven />    <!-- 视图解析器 -->    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>        <!-- 前缀 -->        <property name="prefix" value="/WEB-INF/jsp/" />        <!-- 后缀 -->        <property name="suffix" value=".html" />    </bean></beans>

视图文档 addInfo.html

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>添加信息</title></head><body>    <form action="add.test" method="post">        name : <input type="text" name="name" /><br />        number : <input type="text" name="num" /><br />        phone:<input type="text" name="phone" /><br />        <input type="submit" value="提交" />     </form></body></html>

启动服务器后,在外部浏览器中输入http://localhost:8080/springMVC/addInfo.html,跳转到addInfo.html的页面

这里写图片描述

填入信息后点提交,提交成功后会跳转到成功页面

这里写图片描述

另外查看eclipse控制能打印出所填信息

这里写图片描述

当输入的表单参数为“int”和“String”类型,并且输入格式正确的话,是能正确显示的,但是如果我们在视图addInfo.html文档中加入一个日期格式,就会报“空指针异常”的错误。这是因为当表单提交参数时,会有一个数据绑定DateBind的过程,根据“name”的值把参数注册到对象中。当输入的为“int”和“String”类型时,通过属性编辑器能将其转成正确的数据类型,但是缺少Date类型的属性编辑器,因此要将Date类型正确的注册到对象中,在数据绑定中手动注册一个Date类型属性编辑器。

infoController.java文档

package test.springMVC;import java.text.SimpleDateFormat;import java.util.Date;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.beans.propertyeditors.CustomDateEditor;import org.springframework.validation.BindException;import org.springframework.web.bind.ServletRequestDataBinder;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.AbstractCommandController;@SuppressWarnings("deprecation")public class infoController extends AbstractCommandController {    @Override    protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object command, BindException exception)            throws Exception {        info inf = (info)command;        System.out.println(inf);        return new ModelAndView("addsucc");    }    @Override    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {        // TODO Auto-generated method stub        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));    }}

info.java文档

package test.springMVC;import java.text.SimpleDateFormat;import java.util.Date;public class info {    private String name;    private int num;    private String phone;    private Date schoolDate;    public Date getSchoolDate() {        return schoolDate;    }    public void setSchoolDate(Date schoolDate) {        this.schoolDate = schoolDate;    }    public String getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getNum() {        return num;    }    public void setNum(int num) {        this.num = num;    }    public String toString() {        return name + ";" + num + ";" + phone + ";" + new SimpleDateFormat("yyyy-mm-dd").format(schoolDate);    }}

对应的 addInfo.html也增加一个日期选择框

date : <input type="date" name="schoolDate" />

这样运行之后,控制台就能打印出正确的表单提交的参数

这里写图片描述

2、SimpleFormController

SimpleFormController也是用自动封装表单参数。SimpleFormController有如下一些特点:

1、表单提交方式必须采用“post”方法;

2、相对于AbstractCommandController信息登记和封装成功需要两个控制器来处理,SimpleFormController只需要一个控制器就行,两次请求的地址都是同一个,根据提交方式不同来区分转到的页面,因此在控制器中需要设置formViewsuccessView属性。第一个网址中提交是使用的“GET”方式,因此转到formView对应的页面,第二次表单提交时采用的“post”方式,因此转到successView对应的页面。

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: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.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">                        <!-- 设置映射方式 -->    <bean  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">        <property name="mappings">            <props>                <prop key="addInfo.html">addInfoController</prop>            </props>        </property>    </bean>    <bean id="addInfoController" class="test.springMVC.infoFormController">        <property name="commandClass" value="test.springMVC.info"></property>        <property name="formView" value="addInfo"></property>        <property name="successView" value="addsucc"></property>    </bean>    <!-- 视图解析器 -->    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>        <!-- 前缀 -->        <property name="prefix" value="/WEB-INF/jsp/" />        <!-- 后缀 -->        <property name="suffix" value=".jsp" />    </bean></beans>

infoFormController.java

package test.springMVC;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.propertyeditors.CustomDateEditor;import org.springframework.web.bind.ServletRequestDataBinder;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.SimpleFormController;public class infoFormController extends SimpleFormController {    @Override    protected Map referenceData(HttpServletRequest request) throws Exception {        Map<String, Object> model = new HashMap<String, Object>();        model.put("groupList", new String[]{"group1", "group2"});        return model;    }    @Override    protected ModelAndView onSubmit(Object command) throws Exception {        info inf = (info)command;        System.out.println(inf);        return new ModelAndView("addsucc");    }    @Override    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {        // TODO Auto-generated method stub        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));    }}

addInfo.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ 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=ISO-8859-1"><title>信息添加</title></head><body>    <form action="" method="post"> <!-- 必须指定为post -->        name : <input type="text" name="name" /><br />        number : <input type="text" name="num" /><br />        phone:<input type="text" name="phone" /><br />        group:<select name="group">                    <c:forEach items="${groupList}" var="group">                    <option value="${group}">${group}</option>                    </c:forEach>                </select>        date : <input type="date" name="schoolDate" />        <input type="submit" value="提交" />     </form></body></html>

info.java

package test.springMVC;import java.text.SimpleDateFormat;import java.util.Date;public class info {    private String name;    private int num;    private String phone;    private String group;    private Date schoolDate;    public String getGroup() {        return group;    }    public void setGroup(String group) {        this.group = group;    }    public Date getSchoolDate() {        return schoolDate;    }    public void setSchoolDate(Date schoolDate) {        this.schoolDate = schoolDate;    }    public String getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getNum() {        return num;    }    public void setNum(int num) {        this.num = num;    }    public String toString() {        return name + ";" + num + ";" + phone + ";" + group + ";" + new SimpleDateFormat("yyyy-mm-dd").format(schoolDate);    }}

针对上面给出的代码,对SimpleFormController实现表单数据自动封装的过程总结如下:

  1. 浏览器中输入url:“http://localhost:8080/springMVC/addInfo.html”,通过查找spring-servlet.xml文档,由于是get请求,因此转到formView对应的addInfo.jsp页面。
  2. addInfo.html页面中的<select>标签中的数据来自infoFormController中的“referenceData”方法,因此转到addInfo.html页面之前先获取“referenceData”中的数据,然后在addInfo.html页面页面中显示出来。
  3. 填写信息之后,提交表单,提交的url还是 “http://localhost:8080/springMVC/addInfo.html”。由于表单的提交方式为“post”,因此调用controller中的“onSubmit”方法。
  4. 数据封装成功后,转到successView对应的addsucc.jsp页面。
0 0
原创粉丝点击