• Spring MVC


    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>
  • 相关阅读:
    LeetCode: Next Permutation 解题报告
    LeetCode: Subsets 解题报告
    LeetCode: Recover Binary Search Tree 解题报告
    LeetCode: Find Peak Element 解题报告
    LeetCode: Valid Parentheses 解题报告
    LeetCode: First Missing Positive 解题报告
    LeetCode: Best Time to Buy and Sell Stock III 解题报告
    Nginx系列(二)——流量分发管控
    Nginx系列(一)——HTTP/TCP/UDP负载均衡
    运维电子书PDF汇总
  • 原文地址:https://www.cnblogs.com/zemliu/p/3191565.html
Copyright © 2020-2023  润新知