Spring MVC 简单例子

##简介
Spring自从创建以来,功能愈来愈丰富,从原本的依赖注入(DI)和面向切面编程(AOP)等简单功能发展成了具有MVC、ORM等功能的全能战士,大有一统江湖的态势。本文是个人的学习笔记,仅供参考。本人才疏学浅,如有谬误,还望指正,不胜感激涕零!

##创建项目
用Eclipse创建一个Web项目。本例子命名为SpringMVC。

##引用jar包
本例子使用的Spring版本是4.0.2。以下列出的jar包就只包含名字,不带版本号。

.
├──lib
|  ├── commons-logging-1.0.4.jar
|  ├── spring-context.jar
|  ├── spring-context-support.jar
|  ├── spring-core.jar
|  ├── spring-expression.jar
|  ├── spring-web.jar
|  ├── spring-webmvc.jar
|  ├── spring-beans.jar

##web.xml配置
要使用Spring MVC,配置DispatcherServlet是第一步。它拦截我们自己定义的请求,依据我们定义的规则分发到目标Controller(既Action类)来处理。

例子1:

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

*.do表示会拦截所有以do为后缀的请求。

springmvc表示DispatcherServlet的名字是springmvc。DispatcherServlet可以有多个,通过名字来区别。

在DispatcherServlet的初始化过程中,框架会在web应用的WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean。

当然,你也可以自己指定配置文件名,不使用默认的配置文件名。如下:

<servlet>  
    <servlet-name>springMVC</servlet-name>  
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
    <init-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath*:/springMVC.xml</param-value>  
    </init-param>  
    <load-on-startup>1</load-on-startup>  
</servlet>  
<servlet-mapping>  
    <servlet-name>springMVC</servlet-name>  
    <url-pattern>/</url-pattern>  
</servlet-mapping>  

其中**.xml可以有多种配置写法:

  1. 不写,使用默认值:/WEB-INF/-servlet.xml
  2. /WEB-INF/classes/springMVC.xml
  3. classpath*:springMVC-mvc.xml
  4. 多个值用逗号分隔

PS:本例子使用的是默认的配置文件名。

##springmvc-servlet.xml配置
直接上代码:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    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">

        <!-- 视图解释器 -->
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp" /><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑  -->
        </bean>

        <!-- 控制器 -->
        <bean id="loginController" class="com.wsj.controller.LoginController">
            <property name="username">
                <value>admin</value>
            </property>
            <property name="password">
                <value>admin</value>
            </property>
        </bean>

        <!-- 路径和控制器的映射 -->
        <bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/login.do">loginController</prop>
                </props>
            </property>
        </bean>
</beans>

##控制器

package com.wsj.controller;

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

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

/**
 * 该示例下,一个controller只有一个方法
 * */
public class LoginController implements Controller{

    private String username;

    private String password;

    @Override
    public ModelAndView handleRequest(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        // TODO Auto-generated method stub
        String _username = request.getParameter("username");
        String _pwd =  request.getParameter("password");
        if(username.equals(_username) && password.equals(_pwd)){
            return new ModelAndView("success");
        }
        return new ModelAndView("fail");
    }

    /**
    *getter、setter方法
    */
    ......

}

代码中的控制器实现Controller接口。当login.do的请求分发到该控制器时,默认执行handleRequest的方法。

return new ModelAndView(“success”)表示跳转到success.jsp页面。

##视图与运行
本例子中的视图只有success.jsp和fail.jsp,分别表示登录成功和失败的页面。具体内容就不贴出来了。

在浏览器地址中输入localhost:8081/SpringMVC/login.do?username=admin&password=admin即可调用成功页面。

##能处理多方法的控制器
一个控制器只处理一个方法,感觉总有点奢侈浪费。Spring MVC是支持一个控制器处理多个方法的。

在WEB-INF/jsp里面创建一个名为multi的jsp页面:

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'multi.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
    <h1>请求的方法是:${method }</h1>
  </body>
</html>

创建一个继承MultiActionController的控制器:

package com.wsj.controller;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class UserController extends MultiActionController {

    public ModelAndView add(HttpServletRequest request,
            HttpServletResponse response) {
        System.out.println("Add");
        return new ModelAndView("/multi", "method", "add");
    }

    public ModelAndView update(HttpServletRequest request,
            HttpServletResponse response) {
        System.out.println("Update");
        return new ModelAndView("/multi", "method", "update");
    }
}

代码中,两个方法都调用结束后都返回到multi.jsp页面,同时传一个参数名为method的参数,值分别为各自调用的方法名。

springmvc-servlet.xml中添加如下配置:

<!-- 参数名称解析器,处理一个controller的多个方法。value=action,请求的时候指明action="目标方法" -->
<bean id="paramMethodResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
    <property name="paramName" value="action"/>
</bean>
<!-- 控制器 -->
<bean id="userController" class="com.wsj.controller.UserController">
    <property name="methodNameResolver">
        <ref bean="paramMethodResolver"/>
    </property>
</bean>
<!-- 路径和控制器的映射 -->
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="/login.do">loginController</prop>
            <prop key="/user.do">userController</prop>
        </props>
    </property>
</bean>

参数名称解析器(ParameterMethodNameResolver)是Spring自带的,我们注入即可使用。这个解析器是靠我们配置的paramName的值action来解析请求的。

请求的时候,请使用user.do?action=add类似的来请求。

PS:

  1. 用注解完成Spring MVC的笔记可以参考下一篇博文
    ##参考
  2. 赵磊的博客
  3. 咫尺天涯
  4. catherine的心路历程