1. 流程

Spring MVC依靠的是DispatcherServlet,他是一个分发器,在请求过来的时候它负责分发请求给控制器,当控制器请求处理完成后,它负责根据逻辑视图名查找视图呈现结果

 

2.配置DispatcherServlet

web.xml中DispatcherServlet的配置

    <!-- 定义Spring Dispatcher -->
    <servlet>
        <!-- 这个servlet-name需要与<servlet-name>-servlet.xml对应 -->
        <!-- 否则需要使用init-param指定配置文件 -->
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:spring/config/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

DispatcherServlet的配置文件 dispatcher-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.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 开启Controller自动注册,必须写在这个文件里 -->
    <context:component-scan base-package="com.qunar.controller"/>

    <!-- 开启MVC注解功能 -->
    <mvc:annotation-driven />
    <!-- 静态资源文件请求定向,例如请求是/static/test.js会自动定向到/WEB-INF/static/test.js -->
    <mvc:resources mapping="/static/**" location="/WEB-INF/static/" />
    <mvc:default-servlet-handler/>

    <!-- 配置ControllerURL映射处理bean -->
    <!-- BeanNameUrlHandlerMappping 根据bean的名字将控制器映射到url -->
    <!-- ControllerBeanNameHandlerMapping 根据bean的名字将控制器映射到url,bean名字不需要遵循URL约定 -->
    <!-- ControllerClassNameHandlerMapping 将控制器类名作为URL基础映射到URL -->
    <!-- DefaultAnnotationHandlerMapping 将请求映射到使用@RequestMapping注解的控制器和控制器方法 -->
    <!-- SimpleUrlHandlerMapping 使用定义在Spring应用上下文的属性集合将控制器映射给URL -->
    <!-- 加入不设置这个类,则默认使用 BeanNameUrlHandlerMappping 和 DefaultAnnotationHandlerMapping -->
    <!--<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />-->

    <!-- 设置视图解析器 -->
     <!--InternalResourceViewResolver 使用指定前缀和后缀拼接Controller返回的String得到视图路径 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!-- 设置Tiles视图解析器 -->
    <!--<bean class="org.springframework.web.servlet.view.tiles2.TilesViewResolver" />-->
    <!--&lt;!&ndash; 设置Tiles视图解析器配置 &ndash;&gt;-->
    <!--<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" >-->
        <!--<property name="definitions">-->
            <!--<list>-->
                <!--<value>/WEB-INF/views/**/views.xml</value>-->
            <!--</list>-->
        <!--</property>-->
    <!--</bean>-->
</beans>

 

3.applicationContext配置

<?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"
       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.xsd">

    <!-- 自动注册 -->
    <context:component-scan base-package="com.qunar" >
        <!-- 排除由ServletDispatcher管理的controller包和MyBatis管理的mapper包 -->
        <!--<context:exclude-filter type="regex" expression=".controller.*" />-->
        <!--<context:exclude-filter type="regex" expression=".mapper.*" />-->
        <context:include-filter type="regex" expression=".bean.*" />
        <context:include-filter type="regex" expression=".service.*" />
        <!-- aop中切面包含的bean似乎只能通过显示的bean注册
        不能自动注册,所以此处不写,直接移动到qunarBeans.xml文件 -->
    </context:component-scan>


    <!-- 自动扫描并注册Mapper为MapperFactoryBean,效果和spring的context:component-scan差不多 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.qunar.mapper" />
    </bean>

    <!-- 原先所有的Mapper类都封装成这个MapperFactoryBean -->
    <!--<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
    <!--&lt;!&ndash; 指定sqlSession &ndash;&gt;-->
    <!--<property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
    <!--&lt;!&ndash; 指定映射的实际mapper接口 &ndash;&gt;-->
    <!--<property name="mapperInterface" value="com.qunar.mapper.UserMapper" />-->
    <!--</bean>-->

    <!--<bean id="articleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">-->
    <!--<property name="sqlSessionFactory" ref="sqlSessionFactory" />-->
    <!--<property name="mapperInterface" value="com.qunar.mapper.ArticleMapper" />-->
    <!--</bean>-->


    <!-- 配置spring mutipart解析器,用于文件上传 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
        <property name="maxUploadSize" value="500000" />
    </bean>

</beans>

 

4.典型控制器介绍

package com.qunar.controller;

import com.qunar.bean.Article;
import com.qunar.bean.User;
import com.qunar.mapper.ArticleMapper;
import com.qunar.mapper.UserMapper;
import com.qunar.service.UserServiceIntf;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: zhenwei.liu
 * Date: 13-7-19
 * Time: 下午1:13
 * To change this template use File | Settings | File Templates.
 */
@Controller // 自动注册Controller
@RequestMapping("/user")    // 根url
public class UserController {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserServiceIntf userService;

    @RequestMapping("/list")    // 映射URL
    public ModelAndView listAll() {
        System.out.println("Execute listAll()");
        List<Article> articleList = articleMapper.getUserAticles(1);
        ModelAndView mav = new ModelAndView("list");
        mav.addObject("articleList", articleList);
        userService.buyTicket(1);
        userService.killUser(1);
        userService.trickUser(1);
        return mav;
    }

    // 标明url和请求方法
    @RequestMapping(value = "/showUser", method = RequestMethod.GET)
    // @RequestParam 标明userId的值需要通过reqUserId参数获取
    // 加入没有用@RequestParam,则形参值通过同名的传入参数获取
    public String showUser(
            @RequestParam(value = "reqUserId", defaultValue = "2")
            int userId, Map<String, Object> model) {
        User user = userService.getUserById(userId);
        model.put("user", user);
        System.out.println(user);
        return "show";
    }

    // 显示添加用户的页面
    // params参数标明该方法只接受带有new参数的请求
    @RequestMapping(params = "new", method = RequestMethod.GET)
    public String showAddUser(Model model) {
        // 放入一个空User用于添加用户页面的modelAttribute参数使用
        model.addAttribute("user", new User());
        return "addUser";
    }

    // 添加用户方法
    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
    // @Valid标志需要验证这个user
    public String addUser(@Valid User user,
                          BindingResult bindingResult,
                          @RequestParam(value = "image", required = false)
                          MultipartFile image) {
        // 参数校验失败返回添加页面
        if (bindingResult.hasErrors())
            return "addUser";

        // 处理上传文件
        // 验证文件
        if (!image.isEmpty()) {
            if (!image.getContentType().equals("image/jpeg")) {
                throw new RuntimeException("Only jpg images accepted");
            }
            try {
                File file = new File(System.getProperty("test.root") + File.separator + "resources" +
                    File.separator + image.getName());
                FileUtils.writeByteArrayToFile(file, image.getBytes());
            } catch (IOException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }

        userService.saveUser(user);

        // 动态重定向,可防止重复提交(使用Forward,则可能会重复提交,因为共享了Request和Response)
        return "redirect:/user/" + user.getUsername();
    }

    // 处理动态重定向请求
    @RequestMapping(value = "/{username}", method = RequestMethod.GET)
    // @PathVariable表示username参数来自url,而value={username}则将这个参数填充到URL
    public String showProfile(@PathVariable String username,
                              Model model) {
        model.addAttribute("username", username);
        System.out.println(username);
        return "show";
    }

    public void setArticleMapper(ArticleMapper articleMapper) {
        this.articleMapper = articleMapper;
    }

    public void setUserService(UserServiceIntf userService) {
        this.userService = userService;
    }
}

 

5. 添加用户页面

<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%--
  Created by IntelliJ IDEA.
  User: zhenwei.liu
  Date: 13-7-24
  Time: 下午2:28
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title></title>
</head>
<body>
    <sf:form action="/user/addUser" method="POST" modelAttribute="user" enctype="multipart/form-data">
        <label>username</label><sf:input path="username" />
        <sf:errors path="username" cssClass="error" /> <br>
        <label>userAge</label><sf:input path="userAge" /><br>
        <sf:errors path="userAge" cssClass="error" /> <br>
        <label>userAddress</label><sf:input path="userAddress" /><br>
        <sf:errors path="userAddress" cssClass="error" /> <br>
        <label>image</label><input name="image" type="file"><br>
        <input type="submit" />
    </sf:form>
</body>
</html>

 

 

5.注意的问题

很重要的一个问题是需要注意库依赖引入,引入以后要加入Artifact里面,否则会出现很多莫名其妙的问题,下面是几个需要用到的典型的maven lib

验证器需要用到的lib

        <!-- 验证器 -->
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.2.0.Final</version>
        </dependency>

文件上传和io需要用到的lib

        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.2</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

 

posted on 2013-07-15 17:23  ZimZz  阅读(1363)  评论(0编辑  收藏  举报