springmvc_springmvc执行流程 - CSDN
精华内容
参与话题
  • SpringMvc框架核心技术实战

    千人学习 2020-02-21 11:05:36
    本教程详细的讲解SpringMVC框架的使用,非常详细的案例讲解,一步一步带你走入springmvc框架的核心,使你能够轻松的掌握使用springMVC框架开发java web项目,适应企业级web应用的开发。 教学全程采用笔记+代码...
  • 【Spring】Spring MVC原理及配置详解

    万次阅读 多人点赞 2016-04-28 16:25:36
    【Spring】Spring MVC原理及配置1.Spring MVC概述:Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接...

    【Spring】Spring MVC原理及配置

    1.Spring MVC概述:

    Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中。

    Spring MVC主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成。他的两个核心是两个核心:

    处理器映射:选择使用哪个控制器来处理请求
    视图解析器:选择结果应该如何渲染

    通过以上两点,Spring MVC保证了如何选择控制处理请求和如何选择视图展现输出之间的松耦合。

    2.SpringMVC运行原理

    这里写图片描述

    (1) Http请求:客户端请求提交到DispatcherServlet。
    (2) 寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller。
    (3) 调用处理器:DispatcherServlet将请求提交到Controller。
    (4)(5)调用业务处理和返回结果:Controller调用业务逻辑处理后,返回ModelAndView。
    (6)(7)处理视图映射并返回模型: DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
    (8) Http响应:视图负责将结果显示到客户端。

    3.SpringMVC接口解释

    (1)DispatcherServlet接口
    Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。
    (2)HandlerMapping接口
    能够完成客户请求到Controller映射。
    (3)Controller接口
    需要为并发用户处理上述请求,因此实现Controller接口时,必须保证线程安全并且可重用。
    Controller将处理用户请求,这和Struts Action扮演的角色是一致的。一旦Controller处理完用户请求,则返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View)。
    从宏观角度考虑,DispatcherServlet是整个Web应用的控制器;从微观考虑,Controller是单个Http请求处理过程中的控制器,而ModelAndView是Http请求过程中返回的模型(Model)和视图(View)。
    (4)ViewResolver接口
    Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,从而将相应结果渲染给客户。

    4.DispatcherServlet:

    是整个Spring MVC的核心。它负责接收HTTP请求组织协调Spring MVC的各个组成部分。其主要工作有以下三项:
    (1)截获符合特定格式的URL请求。
    (2)初始化DispatcherServlet上下文对应WebApplicationContext,并将其与业务层、持久化层的WebApplicationContext建立关联。
    (3)初始化Spring MVC的各个组成组件,并装配到DispatcherServlet中。

    5. SpringMVC配置

    项目整体结构如下:
    这里写图片描述
    (1)在web.xml文件中进行配置,在配置中设置springmvc-context.xml的路径,代码如下:

    <servlet>
            <servlet-name>appServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:META-INF/spring/springmvc-context.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>appServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>

    (2)配置springmvc-context.xml文件,这一部分主要是开启注解功能、配置试图解析器,代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns:beans="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" xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
            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 ">
        <mvc:annotation-driven />
        <!-- ①:对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
        <context:component-scan base-package="com.zjn" />
    
        <!-- 这两个类用来启动基于Spring MVC的注解功能,将控制器与方法映射加入到容器中 -->
        <beans:bean
            class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
        <beans:bean
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    
        <!-- 这个类用于Spring MVC视图解析 -->
        <beans:bean id="viewResolver"
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <beans:property name="prefix" value="/WEB-INF/pages/" />
            <beans:property name="suffix" value=".jsp" />
        </beans:bean>
    
    </beans:beans>
    

    (3)配置文件完成了,下面开始写代码,
    两个jsp界面:
    create.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!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=UTF-8">
    <title>Add User From</title>
    </head>
    <body>
        <form action="save" method="post">
            <fieldset>
            <legend>创建用户</legend>
                <p>
                    <label>姓名:</label> <input type="text" id="name" name="name"
                        tabindex="1">
                </p>
                <p>
                    <label>年龄:</label> <input type="text" id="age" name="age"
                        tabindex="2">
                </p>
                <p>
                    <label>密码:</label> <input type="text" id="pwd" name="pwd"
                        tabindex="3">
                </p>
                <p id="buttons">
                    <input id="reset" type="reset" tabindex="4" value="取消"> <input
                        id="submit" type="submit" tabindex="5" value="创建">
                </p>
            </fieldset>
        </form>
    </body>
    </html>

    detail.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!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=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <div id="gloobal">
            <h4>创建成功</h4>
            <p>
            <h5>详情:</h5>
            姓名:${user.name}<br /> 年龄:${user.age}<br /> 密码:${user.pwd}<br />
            </p>
        </div>
    </body>
    </html>

    UserController.java

    package com.zjn.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.zjn.entity.User;
    
    /**
     * 用户管理
     * 
     * @author zjn
     */
    @Controller
    public class UserController {
    
        @RequestMapping("")
        public String Create(Model model) {
            return "create";
        }
    
        @RequestMapping("/save")
        public String Save(@ModelAttribute("form") User user, Model model) { // user:视图层传给控制层的表单对象;model:控制层返回给视图层的对象
            model.addAttribute("user", user);
            return "detail";
        }
    }
    

    User.java

    package com.zjn.entity;
    
    import java.io.Serializable;
    import java.util.Date;
    
    public class User implements Serializable {
        /**
         * @author zjn
         */
        private static final long serialVersionUID = 1L;
        private Integer id; // id
        private String name; // name
        private String pwd; // pwd
        private Integer age; // age
        private Date creatTime; // creatTime
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPwd() {
            return pwd;
        }
    
        public void setPwd(String pwd) {
            this.pwd = pwd;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Date getCreatTime() {
            return creatTime;
        }
    
        public void setCreatTime(Date creatTime) {
            this.creatTime = creatTime;
        }
    
    }

    (4)运行结果

    初始页面:
    这里写图片描述

    输入参数:
    这里写图片描述

    点击创建:
    这里写图片描述

    源码下载地址: SpringMVC项目源码下载

    展开全文
  • SpringMVC框架介绍

    万次阅读 多人点赞 2018-11-08 14:25:19
    史上最全最强SpringMVC详细示例实战教程 SpringMVC学习笔记---- 一、SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包。 2.添加Web.xml配置文件中关于SpringMVC的配置 ...

    这里对SpringMVC框架进行一个简单的介绍:

    springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。
    springmvc是一个基于mvc的web框架。
    springmvc 表现层:方便前后端数据的传输
    Spring MVC 拥有控制器,作用跟Struts类似,接收外部请求,解析参数传给服务层
    MVC是指,C控制层,M模块层,V显示层这样的设计理念,而SSM框架里面SPRING MVC本身就是MVC框架,作用是帮助(某种意义上也可以 理解为约束)我们要按照MVC这样的设计来开发WEB项目,而另外两个框架spring主要是用作IOC,AOF等其他的一些设计原则,至于mybatis是用来方便操作数据库的,所以他们都在MV里面,至于V指的是展示部分,一般是指JSP,freemarks这种前提其实,和SSM就没有太大的关系了

    SpringMVC架构(MVC设计模式在BS系统下的应用)

    在这里插入图片描述

    springmvc项目架构图

    在这里插入图片描述
    Springmvc架构原理解析
    第一步:发起请求到前端控制器(DispatcherServlet)
    第二步:前端控制器请求HandlerMapping查找 Handler
    可以根据xml配置、注解进行查找
    第三步:处理器映射器HandlerMapping向前端控制器返回Handler
    第四步:前端控制器调用处理器适配器去执行Handler
    第五步:处理器适配器去执行Handler
    第六步:Handler执行完成给适配器返回ModelAndView
    第七步:处理器适配器向前端控制器返回ModelAndView
    ModelAndView是springmvc框架的一个底层对象,包括 Model和view
    第八步:前端控制器请求视图解析器去进行视图解析
    根据逻辑视图名解析成真正的视图(jsp)
    第九步:视图解析器向前端控制器返回View
    第十步:前端控制器进行视图渲染
    视图渲染将模型数据(在ModelAndView对象中)填充到request域
    第十一步:前端控制器向用户响应结果

    组件:
    1、前端控制器DispatcherServlet(不需要程序员开发)
    作用接收请求,响应结果,相当于转发器,中央处理器。
    有了DispatcherServlet减少了其它组件之间的耦合度。

    2、处理器映射器HandlerMapping(不需要程序员开发)
    作用:根据请求的url查找Handler

    3、处理器适配器HandlerAdapter
    作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler

    4、处理器Handler(需要程序员开发)
    注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler

    5、视图解析器View resolver(不需要程序员开发)
    作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)

    6、视图View(需要程序员开发jsp)
    View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)

    SpringMVC学习笔记----

    一、SpringMVC基础入门,创建一个HelloWorld程序
    1.首先,导入SpringMVC需要的jar包。

    2.添加Web.xml配置文件中关于SpringMVC的配置

    springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc-servlet.xml springmvc /

    3.在src下添加springmvc-servlet.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>

    <!-- 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 />
    
    <!-- configure the InternalResourceViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
            id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
    

    4.在WEB-INF文件夹下创建名为jsp的文件夹,用来存放jsp视图。创建一个hello.jsp,在body中添加“Hello World”。

    5.建立包及Controller,如下所示

    6.编写Controller代码

    @Controller
    @RequestMapping("/mvc")
    public class mvcController {

    @RequestMapping("/hello")
    public String hello(){        
        return "hello";
    }
    

    }

    7.启动服务器,键入 http://localhost:8080/项目名/mvc/hello

    二、配置解析
    1.Dispatcherservlet

    DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。

    2.InternalResourceViewResolver

    视图名称解析器

    3.以上出现的注解

    @Controller 负责注册一个bean 到spring 上下文中

    @RequestMapping 注解为控制器指定可以处理哪些 URL 请求

    三、SpringMVC常用注解
    @Controller

    负责注册一个bean 到spring 上下文中
    @RequestMapping

    注解为控制器指定可以处理哪些 URL 请求
    @RequestBody

    该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上

    @ResponseBody

    该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

    @ModelAttribute

    在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法

    在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中

    @RequestParam

    在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法

    @PathVariable

    绑定 URL 占位符到入参
    @ExceptionHandler

    注解到方法上,出现异常时会执行该方法
    @ControllerAdvice

    使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常

    四、自动匹配参数

    //match automatically
    @RequestMapping("/person")
    public String toPerson(String name,double age){
        System.out.println(name+" "+age);
        return "hello";
    }
    

    五、自动装箱
    1.编写一个Person实体类

    package test.SpringMVC.model;

    public class Person {
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
    private String name;
    private int age;

    }

    2.在Controller里编写方法

    //boxing automatically
    @RequestMapping("/person1")
    public String toPerson(Person p){
        System.out.println(p.getName()+" "+p.getAge());
        return "hello";
    }
    

    六、使用InitBinder来处理Date类型的参数

    //the parameter was converted in initBinder
    @RequestMapping("/date")
    public String date(Date date){
        System.out.println(date);
        return "hello";
    }
    
    //At the time of initialization,convert the type "String" to type "date"
    @InitBinder
    public void initBinder(ServletRequestDataBinder binder){
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),
                true));
    }
    

    七、向前台传递参数

    //pass the parameters to front-end
    @RequestMapping("/show")
    public String showPerson(Map<String,Object> map){
        Person p =new Person();
        map.put("p", p);
        p.setAge(20);
        p.setName("jayjay");
        return "show";
    }
    

    前台可在Request域中取到"p"

    八、使用Ajax调用

    //pass the parameters to front-end using ajax
    @RequestMapping("/getPerson")
    public void getPerson(String name,PrintWriter pw){
        pw.write("hello,"+name);        
    }
    @RequestMapping("/name")
    public String sayHello(){
        return "name";
    }
    

    前台用下面的Jquery代码调用

          $(function(){
              $("#btn").click(function(){
                  $.post("mvc/getPerson",{name:$("#name").val()},function(data){
                      alert(data);
                  });
              });
          });
    

    九、在Controller中使用redirect方式处理请求
    //redirect
    @RequestMapping("/redirect")
    public String redirect(){
    return “redirect:hello”;
    }
    十、文件上传
    1.需要导入两个jar包

    2.在SpringMVC配置文件中加入

    <!-- upload settings -->
    <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="102400000"></property>
    </bean>
    

    3.方法代码

    @RequestMapping(value="/upload",method=RequestMethod.POST)
    public String upload(HttpServletRequest req) throws Exception{
        MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req;
        MultipartFile file = mreq.getFile("file");
        String fileName = file.getOriginalFilename();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");        
        FileOutputStream fos = new FileOutputStream(req.getSession().getServletContext().getRealPath("/")+
                "upload/"+sdf.format(new Date())+fileName.substring(fileName.lastIndexOf('.')));
        fos.write(file.getBytes());
        fos.flush();
        fos.close();
        
        return "hello";
    }
    

    4.前台form表单

      <form action="mvc/upload" method="post" enctype="multipart/form-data">
          <input type="file" name="file"><br>
          <input type="submit" value="submit">
      </form>
    

    十一、使用@RequestParam注解指定参数的name

    @Controller
    @RequestMapping("/test")
    public class mvcController1 {
    @RequestMapping(value="/param")
    public String testRequestParam(@RequestParam(value=“id”) Integer id,
    @RequestParam(value=“name”)String name){
    System.out.println(id+" "+name);
    return “/hello”;
    }
    }

    十二、RESTFul风格的SringMVC
    1.RestController

    @Controller
    @RequestMapping("/rest")
    public class RestController {
    @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
    public String get(@PathVariable(“id”) Integer id){
    System.out.println(“get”+id);
    return “/hello”;
    }

    @RequestMapping(value="/user/{id}",method=RequestMethod.POST)
    public String post(@PathVariable("id") Integer id){
        System.out.println("post"+id);
        return "/hello";
    }
    
    @RequestMapping(value="/user/{id}",method=RequestMethod.PUT)
    public String put(@PathVariable("id") Integer id){
        System.out.println("put"+id);
        return "/hello";
    }
    
    @RequestMapping(value="/user/{id}",method=RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id){
        System.out.println("delete"+id);
        return "/hello";
    }
    

    }

    2.form表单发送put和delete请求

    在web.xml中配置

    HiddenHttpMethodFilter org.springframework.web.filter.HiddenHttpMethodFilter HiddenHttpMethodFilter /*

    在前台可以用以下代码产生请求

    <form action="rest/user/1" method="post">
        <input type="hidden" name="_method" value="PUT">
        <input type="submit" value="put">
    </form>
    
    <form action="rest/user/1" method="post">
        <input type="submit" value="post">
    </form>
    
    <form action="rest/user/1" method="get">
        <input type="submit" value="get">
    </form>
    
    <form action="rest/user/1" method="post">
        <input type="hidden" name="_method" value="DELETE">
        <input type="submit" value="delete">
    </form>
    

    十三、返回json格式的字符串
    1.导入以下jar包

    2.方法代码

    @Controller
    @RequestMapping("/json")
    public class jsonController {

    @ResponseBody
    @RequestMapping("/user")
    public  User get(){
        User u = new User();
        u.setId(1);
        u.setName("jayjay");
        u.setBirth(new Date());
        return u;
    }
    

    }

    十四、异常的处理
    1.处理局部异常(Controller内)

    @ExceptionHandler
    public ModelAndView exceptionHandler(Exception ex){
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex);
        System.out.println("in testExceptionHandler");
        return mv;
    }
    
    @RequestMapping("/error")
    public String error(){
        int i = 5/0;
        return "hello";
    }
    

    2.处理全局异常(所有Controller)

    @ControllerAdvice
    public class testControllerAdvice {
    @ExceptionHandler
    public ModelAndView exceptionHandler(Exception ex){
    ModelAndView mv = new ModelAndView(“error”);
    mv.addObject(“exception”, ex);
    System.out.println(“in testControllerAdvice”);
    return mv;
    }
    }

    3.另一种处理全局异常的方法

    在SpringMVC配置文件中配置

    <!-- configure SimpleMappingExceptionResolver -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">error</prop>
            </props>
        </property>
    </bean>
    

    error是出错页面

    十五、设置一个自定义拦截器
    1.创建一个MyInterceptor类,并实现HandlerInterceptor接口

    public class MyInterceptor implements HandlerInterceptor {

    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        System.out.println("afterCompletion");
    }
    
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        System.out.println("postHandle");
    }
    
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        System.out.println("preHandle");
        return true;
    }
    

    }

    2.在SpringMVC的配置文件中配置

    <!-- interceptor setting -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/mvc/**"/>
            <bean class="test.SpringMVC.Interceptor.MyInterceptor"></bean>
        </mvc:interceptor>        
    </mvc:interceptors>
    

    3.拦截器执行顺序

    十六、表单的验证(使用Hibernate-validate)及国际化
    1.导入Hibernate-validate需要的jar包

    (未选中不用导入)

    2.编写实体类User并加上验证注解

    public class User {
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Date getBirth() {
    return birth;
    }
    public void setBirth(Date birth) {
    this.birth = birth;
    }
    @Override
    public String toString() {
    return “User [id=” + id + “, name=” + name + “, birth=” + birth + “]”;
    }
    private int id;
    @NotEmpty
    private String name;

    @Past
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birth;
    

    }

    ps:@Past表示时间必须是一个过去值

    3.在jsp中使用SpringMVC的form表单

    <form:form action="form/add" method="post" modelAttribute="user">
        id:<form:input path="id"/><form:errors path="id"/><br>
        name:<form:input path="name"/><form:errors path="name"/><br>
        birth:<form:input path="birth"/><form:errors path="birth"/>
        <input type="submit" value="submit">
    </form:form> 
    

    ps:path对应name

    4.Controller中代码

    @Controller
    @RequestMapping("/form")
    public class formController {
    @RequestMapping(value="/add",method=RequestMethod.POST)
    public String add(@Valid User u,BindingResult br){
    if(br.getErrorCount()>0){
    return “addUser”;
    }
    return “showUser”;
    }

    @RequestMapping(value="/add",method=RequestMethod.GET)
    public String add(Map<String,Object> map){
        map.put("user",new User());
        return "addUser";
    }
    

    }

    ps:

    1.因为jsp中使用了modelAttribute属性,所以必须在request域中有一个"user".

    2.@Valid 表示按照在实体上标记的注解验证参数

    3.返回到原页面错误信息回回显,表单也会回显

    5.错误信息自定义

    在src目录下添加locale.properties

    NotEmpty.user.name=name can’t not be empty
    Past.user.birth=birth should be a past value
    DateTimeFormat.user.birth=the format of input is wrong
    typeMismatch.user.birth=the format of input is wrong
    typeMismatch.user.id=the format of input is wrong
    在SpringMVC配置文件中配置

    <!-- configure the locale resource -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="basename" value="locale"></property>
    </bean>
    

    6.国际化显示

    在src下添加locale_zh_CN.properties

    username=账号
    password=密码
    locale.properties中添加

    username=user name
    password=password
    创建一个locale.jsp

    在SpringMVC中配置
    <!-- make the jsp page can be visited -->
    <mvc:view-controller path="/locale" view-name="locale"/>
    

    让locale.jsp在WEB-INF下也能直接访问

    最后,访问locale.jsp,切换浏览器语言,能看到账号和密码的语言也切换了

    十七、压轴大戏–整合SpringIOC和SpringMVC
    1.创建一个test.SpringMVC.integrate的包用来演示整合,并创建各类

    2.User实体类

    public class User {
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public Date getBirth() {
    return birth;
    }
    public void setBirth(Date birth) {
    this.birth = birth;
    }
    @Override
    public String toString() {
    return “User [id=” + id + “, name=” + name + “, birth=” + birth + “]”;
    }
    private int id;
    @NotEmpty
    private String name;

    @Past
    @DateTimeFormat(pattern="yyyy-MM-dd")
    private Date birth;
    

    }

    3.UserService类

    @Component
    public class UserService {
    public UserService(){
    System.out.println(“UserService Constructor…\n\n\n\n\n\n”);
    }

    public void save(){
        System.out.println("save");
    }
    

    }

    4.UserController

    @Controller
    @RequestMapping("/integrate")
    public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/user")
    public String saveUser(@RequestBody @ModelAttribute User u){
        System.out.println(u);
        userService.save();
        return "hello";
    }
    

    }

    5.Spring配置文件

    在src目录下创建SpringIOC的配置文件applicationContext.xml

    <?xml version="1.0" encoding="UTF-8"?>


    <context:component-scan base-package=“test.SpringMVC.integrate”>
    <context:exclude-filter type=“annotation”
    expression=“org.springframework.stereotype.Controller”/>
    <context:exclude-filter type=“annotation”
    expression=“org.springframework.web.bind.annotation.ControllerAdvice”/>
    </context:component-scan>

    在Web.xml中添加配置

    org.springframework.web.context.ContextLoaderListener contextConfigLocation classpath:applicationContext.xml

    6.在SpringMVC中进行一些配置,防止SpringMVC和SpringIOC对同一个对象的管理重合

    <context:component-scan base-package="test.SpringMVC.integrate">
        <context:include-filter type="annotation" 
            expression="org.springframework.stereotype.Controller"/>
        <context:include-filter type="annotation" 
            expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
    </context:component-scan>
    

    十八、SpringMVC详细运行流程图

    十九、SpringMVC运行原理

    1. 客户端请求提交到DispatcherServlet
    2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
    3. DispatcherServlet将请求提交到Controller
    4. Controller调用业务逻辑处理后,返回ModelAndView
    5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
    6. 视图负责将结果显示到客户端

    二十、SpringMVC与struts2的区别
    1、springmvc基于方法开发的,struts2基于类开发的。springmvc将url和controller里的方法映射。映射成功后springmvc生成一个Handler对象,对象中只包括了一个method。方法执行结束,形参数据销毁。springmvc的controller开发类似web service开发。
    2、springmvc可以进行单例开发,并且建议使用单例开发,struts2通过类的成员变量接收参数,无法使用单例,只能使用多例。
    3、经过实际测试,struts2速度慢,在于使用struts标签,如果使用struts建议使用jstl。

    展开全文
  • springmvc 从入门到总结

    千次阅读 多人点赞 2017-10-31 15:56:41
    springMvc的总结:(推荐,总共有十五章) http://www.cnblogs.com/liukemng/p/3751338.html 框架 拦截器不拦截静态资源 http://www.cnblogs.com/banning/p/6195072.html Spring 学习版本: 4.3.0 框架认识 框架学...

    springMvc的总结:(推荐,总共有十五章)

    http://www.cnblogs.com/liukemng/p/3751338.html

    框架

    拦截器不拦截静态资源

    http://www.cnblogs.com/banning/p/6195072.html

    Spring

    学习版本: 4.3.0

    框架认识

    框架学起来比较简单

    但也有难的地方,难是难在底层原理

     

    用了框架之后,写代码就非常简单,因为框架会完成一部分代码,

    我们只要按框架的规则去使用就可以了

     

    学习框架的方法:

    与学习初级基础有所不同,

    基础学习都是学习基本语法,完成简单的案例,逐步理解面向对象的编程思想.

    框架属于中高级的学习,要运用面向对象的进行编程,接口编程

    能够自已完成业务.熟悉业务.能够架构一个项目,属性框架的原理

     

    框架学习程度:

    相用框架

    理解框架原理、走源码

    自己编写框架部分

    框架的由来

    Md1

    Md2

    Jsp/servlet 的 mvc回顾

     

    当一个方法中有部分代码在不断重复时,抽取出来做一个方法

    当很多类在操作同一段代码时,抽出来做一个类

    当很多类在做同一类事情的时候,抽出来做一个jar包或做成框架

     

    这就是框架

    框架,替程序员完成一部分代码,从而提高开发效率

    框架就是一个模板,

    Web应用的框架:webwork,jsf, struts1, struts2,springmvc

     

    Mvc框架的工作

    Servlet:

    将页面请求映射到java类,也就是后台

    接收并处理页面提交的数据

    调用业务逻辑方法处理业务结果,将数据封装准备渲染到页面

    控制页面跳转

     

    Mvc的V层:

    将页面请求映射到java类,也就是后台

    获取并封装好页面提交的数据

    渲染数据到页面

    控制页面跳转  

     

     

    Spring下载

    http://repo.springsource.org/libs-release-local/org/springframework/spring

     

    向下拉选中需要下载的版本。

     

    点击相应需要下载的zip,window版本直接下zip即可

     

    Spring mvc

    Spring mvc是一个轻量级的基于请求响应的mvc框架。Mvc框架一般都是基于请求响应的(JSF是基于事件驱动的框架)。

    Spring mvc的优势:

    1. 性能较struts2好(struts2是快速开发)

    2. Spring mvc使用简单,配置便捷,易上手

    3. 天生与spring无缝集成(使用spring的IOC和AOP)(struts2也有可以与spring集成,但是需要插件需要配置)

    4. 使用约定大于配置(只要遵守spring mvc的配置约定,那么编码非常简结)

    5. 能进行简单的junit测试

    6. 支持restful风格

    7. 异常处理

    8. 本地化、国际化、数据验证、类型转换等等

    9. 拦截器

    使用的人多,使用的公司多  

      

     

    Spring mvc 简单的结构流程图

     

     

     

     

     

     

    Springmvc工作流程描述

          1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;

          2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象

          (包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;

          3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法

          4.  提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:

          HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息

          数据转换:对请求消息进行数据转换。如String转换成Integer、Double等

          数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等

          数据验证验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中

          5.  Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;

          6.  根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;

          7. ViewResolver 结合Model和View,来渲染视图

          8. 将渲染结果返回给客户端。

    Hello spring mvc配置开发

    1. 导入jar

    commons-logging-1.1.3.jar

    jstl-2.4.jar

    servlet-api.jar

    spring-beans-4.3.0.RELEASE.jar

    spring-context-4.3.0.RELEASE.jar

    spring-context-support-4.3.0.RELEASE.jar

    spring-core-4.3.0.RELEASE.jar

    spring-expression-4.3.0.RELEASE.jar

    spring-web-4.3.0.RELEASE.jar

    spring-webmvc-4.3.0.RELEASE.jar

     

    2. 配置web.xml,配置spring mvc的分发器(和servlet配置一样)DispatcherServlet,需要在tomcat启动的时候就加载

    <load-on-startup>1</load-on-startup>

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

     

    3. 添加springmvc的配置文件,默认在src下添加dispatcherServletName-servlet.xml,

        注意:dispatcherServletName是web.xml中servlet-name的值,根据这里的配置,应该叫:springmvc-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: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.xsd

                                http://www.springframework.org/schema/context

                                http://www.springframework.org/schema/context/spring-context.xsd">

     

    </beans>

      

    注:这个配置文件中的内容如何不会写,那么可以到spring的zip中找到dosc/spring-frameworkreference/html

    找到The Web模块下的The DispatcherServlet 下的Default DispatcherServlet Configuration配置

     

     

     

    4. 编写Controller     

    public class HelloControllerimplements Controller{

    @Override

    public ModelAndView handleRequest(HttpServletRequestarg0, HttpServletResponsearg1) throws Exception {

    //ModelAndView是封装要显示到页面的数据

    ModelAndView mv =new ModelAndView();

    //页面的数据

    mv.addObject("msg","你好 spring mvc");

    //配置视图的名称

    mv.setViewName("hello");

    return mv;

    }

    }

     

    5. 配置springmvc配置文件(给第3步的配置文件添加内容)

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

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd">

        <!-- 配置HandlerMapping -->

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

    <!-- 配置HandlerAdapter -->

    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置页面渲染器,到dosc/html/index.html中搜索Reslover可以找到 -->

    <bean id="jspViewResolver" 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 name="/hello.do" class="com.yirong.controller.HelloController"></bean>

    </beans>

     

    6. 请求结果

     

     

    Spring mvc注解开发

    1. 倒入jar

    commons-logging-1.1.3.jar

    jstl-2.4.jar

    servlet-api.jar

    spring-aop-4.3.0.RELEASE.jar

    spring-beans-4.3.0.RELEASE.jar

    spring-context-4.3.0.RELEASE.jar

    spring-context-support-4.3.0.RELEASE.jar

    spring-core-4.3.0.RELEASE.jar

    spring-expression-4.3.0.RELEASE.jar

    spring-web-4.3.0.RELEASE.jar

    spring-webmvc-4.3.0.RELEASE.jar

     

    2. 配置web.xml

    <!-- 注解的方式 -->

    <servlet>

    <servlet-name>springmvc</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <init-param>  <!-- 到the web文档中可以查找获得-->

    <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>*.do</url-pattern>

    </servlet-mapping>

     

    3. 编写controller

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

     

    @Controller //表示这个是一个Controller 

    public class HelloWorldController {

    @RequestMapping("/helloWorld") //请求此方法

    public String helloWorld(Modelmodel) {

    model.addAttribute("msg","Hello World! 你好springmvc注解 ");

    return "hello";//视图的名称

    }

    @RequestMapping("/helloWorld1")//请求此方法

    public ModelAndView helloWorldreq(HttpServletRequestarg0, HttpServletResponsearg1) throws Exception {

    //ModelAndView是封装要显示到页面的数据

    ModelAndView mv =new ModelAndView();

    //页面的数据

    mv.addObject("msg","你好 spring mvc");

    //配置视图的名称

    mv.setViewName("hello");

    return mv;

    }

    }

     

     

    4. 配置springmvc.xml,这个文件需要和源码放在一起src/*.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: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.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀,页面路径默认在webContent下-->

       <property name="prefix" value="/WEB-INF/jsp/"/>

       <property name="suffix" value=".jsp"/>

        </bean>

    <!--扫描这个文件夹下的类表示是注解的controller。 到the web文档中可以查找获得-->

     <context:component-scan base-package="com.yirong.controller.annotation" />

    </beans>

     

    5. 效果:

     

     

    Controller配置方式

    1. 配置开发

    2. 注解开发

    3. Key对应url请求名的方式

     

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

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd">

        <!-- 配置HandlerMapping -->

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

    <!-- 配置HandlerAdapter 如果这里不配置,那么请求一定要带上web中配置的结尾,比如.do-->

    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀,页面路径默认在webContent下-->

       <property name="prefix" value="/WEB-INF/jsp/"/>

       <property name="suffix" value=".jsp"/>

    </bean>

     

        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

        <property name="mappings">

        <props>

        <prop key="/hello.do">helloController</prop>

        </props>

        </property>

        </bean> 

    <bean name="helloController" class="com.yirong.controller.HelloController"></bean>

         

        

    </beans>

     

     

    4. 控制器类名的方式配置

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

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd">

        <!-- 配置HandlerMapping -->

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>

    <!-- 配置HandlerAdapter 如果这里不配置,那么请求一定要带上web中配置的结尾,比如.do-->

    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀页面默认在webContent下-->

       <property name="prefix" value="/WEB-INF/jsp/"/>

       <property name="suffix" value=".jsp"/>

        </bean> 

        <!-- 控制器类名的方式配置 hello*.do的请求将被匹配-->

        <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

        <bean name="helloController" class="com.yirong.controller.HelloController"></bean>

    </beans>

     

     

    Spring mvc结果跳转

    1. 设置 ModelAndView对象,视图解释器根据设置的view的名称进行跳转

    视图解释器根据springmvc配置文件中的页面的前缀路径+视图名称+springmvc配置文件中的页面的后缀,找到指定页面。

    @Override

    public ModelAndView handleRequest(HttpServletRequestarg0, HttpServletResponsearg1) throws Exception {

    //ModelAndView是封装要显示到页面的数据

    ModelAndView mv =new ModelAndView();

    //页面的数据

    mv.addObject("msg","你好 spring mvc");

    //配置视图的名称

    mv.setViewName("hello");

    return mv;

    }

    @RequestMapping("/helloWorld")//请求此方法

    public String helloWorld(Modelmodel) {

    model.addAttribute("msg","Hello World! 你好springmvc注解 ");

    return "hello";//视图的名称

    }

     

    2. 通过servletApi跳转,不使用springmvc的视图解释器

    @RequestMapping("/helloWorld1")//请求此方法

    public voidhelloWorldreq(HttpServletRequest arg0, HttpServletResponsearg1) throws Exception {

    arg1.getWriter().println("你好,springmvc servlet");

            //servlet的重定向和转向设置值等在这里都可以使用

    }

     

    3. Springmvc实现重定向和转发,没有视图渲染,页面在webcontent,转发,需要带上.jsp没有用到视图渲染器

    @RequestMapping("/zhuanfa")

    public String zhuanfa(){

     return "forward:zhuanfa.jsp"; //转发 地址栏不变

                //return "redirect:zhuangxiang.jsp"; //转向 地址栏变

    }

     

    4. Springmvc实现重定向和转发,视图渲染器,转向不需要视图渲染

    @RequestMapping("/zhuanfa")

    public String zhuanfa(){

    return "zhuanfa"; //默认转发

    }

     

    Spring mvc 是单例的

    1. controller添加一个构造方法,在启动时执行一次,而后访问时不会再执行

    public HelloWorldController(){

    System.out.println("spring mvc 构造方式");

    }

     

     

     

    Spring mvc接收页面简单数据

    1. 创建一个注解方式的spring mvc项目环境,在controller中添加以下方法

    /**

     * url参数数据提交,在这里获取数据

     * @param name

     * @return

     */

    @RequestMapping("/datas")

    public String getData(Stringname){

    System.out.println(name);

    return "wel";

    }

     

    2. 访问,注意参数名与上面方法名的形参名相同

    http://localhost:8080/springMvcTest/datas.do?name=aacc

     

     

    3. 如果url上的参数名与方法是的形参名不同也可以传递参数,改造方法:

    /**

     * url参数数据提交,在这里获取数据

     * @param name

     * @return

     */

    @RequestMapping("/datas")

    public String getData(@RequestParam("un")Stringname){

    System.out.println(name);

    return "wel";

    }

     

    4. 访问

    http://localhost:8080/springMvcTest/datas.do?un=aaccsdf

     

     

     Spring mvc接收对象数据

    要求表单中的name的名称与实体的属性名相同,controller中的方法的形参是实体的对象即可。

    spring mvc对基本数据类型会自动转换。

    Spring mvc会将传递的值封装到对象中去,并且与形参的名称没有关系。

    1. controller中添加一个方法

    /**

     * url参数数据提交,在这里获取对象数据

     * @param name

     * @return

     */

    @RequestMapping("/dataObj")

    public String getDataObj(User user){

    System.out.println(user.toString());

    return "wel";

    }

     

    2. 添加User对象,属性需要有get set方法

    package com.yirong.controller.annotation;

     

    public class User {

    private Stringname;

    private Integerage;

    private Stringtel;

     

    public String getName() {

    return name;

    }

    public void setName(Stringname) {

    this.name =name;

    }

    public Integer getAge() {

    return age;

    }

    public void setAge(Integerage) {

    this.age =age;

    }

    public String getTel() {

    return tel;

    }

    public void setTel(Stringtel) {

    this.tel =tel;

    }

    @Override

    public String toString() {

    return "User [name=" +name + ", age=" + age +", tel=" + tel + "]";

    }

    }

     

     

    3. 效果

    http://localhost:8080/springMvcTest/dataObj.do?name=myname&age=1

     

     

    Spring mvc将数据显示到UI

    ModelAndView的方式

    public class HelloControllerimplements Controller{

    @Override

    public ModelAndView handleRequest(HttpServletRequestarg0, HttpServletResponsearg1) throws Exception {

    //ModelAndView是封装要显示到页面的数据 

    //这相当于是request.setAttribute的方式

    ModelAndView mv =new ModelAndView();  

    //页面的数据

    mv.addObject("msg","你好 spring mvc");

    //配置视图的名称

    mv.setViewName("hello");

    return mv;

    }

    }

     

     

    1. 页面用el表达式即可

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>springmvc转发</title>

    </head>

    <body>

    springmvc转发sdf

    <br> 

    ${msg}

    </body>

    </html

     

    ModelMap的方式

    1. 注:modelmap一定要放在controller的方法中做为形参

    /**

     * url参数数据提交,在这里获取对象数据

     * @param name

     * @return

     */

    @RequestMapping("/dataObj")

    public String getDataObj(Useruser,ModelMap modelMap){

    System.out.println(user.toString());

    //将数据显示到页面

    modelMap.addAttribute("myvalue","值,va");

    return "wel";

    }

     

    2. 页面

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>springmvc转发</title>

    </head>

    <body>

    springmvc转发sdf

    <br> 

    ${myvalue }

    </body>

    </html>

     

    3. 效果

     

     

     

    ModelAndView与ModelMap方式比较

    相同点:都可以将数据封装显示到视图

    不同点:ModelAndView可以指定跳转的视图,而ModelMap不能

    ModelAndView需要视图解析器,ModelMap可以不需要

    Spring mvc解决乱码

    Get方式乱码

    配置tomcat即可

    找到conf/server.xml中端口设置的地方,添加 URIEncoding="UTF-8"

    添加完成之后:

     <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"  URIEncoding="UTF-8" />

     

    1. 传递中文到controller

    /**

     * url参数数据提交,在这里获取数据

     * @param name

     * @return

     */

    @RequestMapping("/datas")

    public String getData(@RequestParam("un")Stringname,ModelMap map){

    System.out.println(name);

            map.addAttribute(“myvalue”,name);

    return "wel";

    }

     http://localhost:8080/springMvcTest/datas.do?un=你好springmvc

    2. 效果,中文在controller中拿到是乱码

    解决之前:乱码

             

    解决之后:

             

    再传递到页面(注:页面的编码要是utf-8,浏览器的编码也需要是utf-8):

     

     

    Post方式乱码

    Spring mvc 中解决乱码是通过CharacterEncodingFilter过滤器来解决的,因此需要在web.xml中配置。并且CharacterEncodingFilter主要是用于解决post请求的乱码,

    get请求方式的乱码需要用到tomcat或jsp页面设置的方式进行解决

    注:此配置需要配置在DispatcherServlet之前

    <filter>

    <filter-name>CharacterEncodingFilter</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

    <param-name>encoding</param-name>

    <param-value>utf-8</param-value>

    </init-param>

    </filter>

    <filter-mapping>

    <filter-name>CharacterEncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    1. 页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>乱码解决</title>

    </head>

    <body>

     <form action="/springMvcTest/datas.do" method="post">

     <input type="text" name="un" />

     <input type="submit" value="提交" />

     </form>

    </body>

    </html>

    2. 效果:

     

     

     

     

    Spring mvc url请求风格1

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

     

    @Controller //表示这个是一个Controller

    @RequestMapping("/hello2")

    public class Hello2Controller {

    @RequestMapping(params="method=add",method=RequestMethod.POST) //请求此方法一定要是post方式

    public String helloWorld(Model model) {

    model.addAttribute("msg", "Hello World! 你好springmvc注解  params");

    return "WEB-INF/jsp/hello"; //视图的名称

    }

    }

     

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

     

    @Controller //表示这个是一个Controller

    @RequestMapping("/hello2")

    public class Hello2Controller {

    @RequestMapping(params="method=add",method=RequestMethod.GET)  //请求此方法一定要是GET方式

    public String helloWorld(Model model) {

    model.addAttribute("msg", "Hello World! 你好springmvc注解  params");

    return "WEB-INF/jsp/hello"; //视图的名称

    }

    }

     

     

    Restful风格@PathVariable

    Restful风格:轻量级,安全,效率高

    Controller中的方法:

    @RequestMapping("/{uid}/del/{id}")

    public String del(@PathVariable Integerid,@PathVariable("uid") Integer uid,ModelMapmodelMap){

    System.out.println(id);

    System.out.println(uid);

    //将数据显示到页面

    modelMap.addAttribute("myvalue",id);

    return "wel";

    }

    @PathVariable表示这个参数是路径带过来的参数

    Restful风格的写法还可以这样:

    @RequestMapping("/del/{id}/{uid}")

    @RequestMapping("/{id}/del//{uid}")

     

    效果:

    http://localhost:8080/springMvcTest/111/del/222.do

     

     

    详解@RequestMapping

    @RequestMapping可以修饰在类上面,表示指定的目录为这个类请求的url,也可以修饰在方法上面表示请求的是某个方法

    标识url的方式:@RequestMapping(“url”)

    表识参数和方法还有头的请求方式:

    @RequestMapping(value="/rmtest",params={"name","age!=10"},method=RequestMethod.GET,headers={"Accept-Language=zh-CN,zh;q=0.8"})

    Value表示:url

    Params表示:请求的url必须带上指定参数,而且age的值!=10,否则404

    Method表示:请求的方式一定指定方式,这里是GET,否则404

    Headers表示:http请求的头的内容,其中这里指定Accept-Language的值一定要是zh-CN,zh;q=0.8,否则404

     

    :

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

     

    @Controller //表示这个是一个Controller

    public class RmTest {

    @RequestMapping(value="/rmtest",params={"name","age!=10"},method=RequestMethod.GET,headers={"Accept-Language=zh-CN,zh;q=0.8"})//请求此方法

    public String helloWorld(Modelmodel) {

    model.addAttribute("msg","Hello World! 你好springmvc注解  rmtest");

    return "WEB-INF/jsp/hello";//视图的名称

    }

    }

     

    效果:

     

     

     

    详解@RequestMapping ant风格url

    此方式了解即可

    Ant风格资源地址支持3种匹配符:

     ? : 匹配文件名中的一个字符

     * : 匹配文件名中的任意字符

    ** :  匹配多层路径

    @RequestMapping对ant风格url的支持,例:

     

     

    :

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

     

    @Controller //表示这个是一个Controller

    public class RmTest {

    @RequestMapping("/antUrl/*/t")//请求此方法

    public String testAntUrl(Modelmodel) {

    model.addAttribute("msg","Hello World! 你好springmvc注解  anturl");

    return "WEB-INF/jsp/hello";//视图的名称

    }

    }

     

     

    详解@PathVariable

     

    详解Restful

     

     

    http://kb.cnblogs.com/page/186516/

    http://www.infoq.com/cn/articles/rest-introduction

     

    比如:

     

    案例

     

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.PathVariable;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

     

    @Controller // 表示这个是一个Controller

    public class RestfulTest {

     

    @RequestMapping(value="/testRestfulUrl",method=RequestMethod.POST)

    public String add(Ordero, Model model) {

    System.out.println(o.toString());

    model.addAttribute("msg","Hello World! 你好springmvc注解  restful 添加 post 请求");

    return "order/add";

    }

     

    @RequestMapping(value="/testRestfulUrl/{id}",method=RequestMethod.GET)

    public String get(@PathVariable("id") Integer id, Modelmodel) {

    System.out.println(id);

    model.addAttribute("msg","Hello World! 你好springmvc注解  restful 通过id查一个对象的信息 get请求");

    return "order/add";

    }

    @RequestMapping(value="/testRestfulUrl/{id}",method=RequestMethod.DELETE)

    public String delete(@PathVariable("id") Integer id, Modelmodel) {

    System.out.println(id);

    model.addAttribute("msg","Hello World! 你好springmvc注解  restful 删除 delete请求");

    return "order/add";

    }

     

    @RequestMapping(value="/testRestfulUrl/{id}",method=RequestMethod.PUT)

    public String put(@PathVariable("id") Integer id, Modelmodel) {

    System.out.println(id);

    model.addAttribute("msg","Hello World! 你好springmvc注解  restful 修改 put请求");

    return "order/add";

    }

    }

     

     

    页面:webContent/order/下

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    添加:<br />

     <form action="/springMvcTest/testRestfulUrl.do" method="post">

     <input type="text" name="orderName" />

     <input type="text" name="number" />

     <input type="submit" value="提交" />

     </form>

     获得:<br />

     <a href="/springMvcTest/testRestfulUrl.do/1">获取id=1的数据</a>

     

     删除:<br />

      <form action="/springMvcTest/testRestfulUrl.do/1" method="post">

     <input type="hidden" name="_method" value="DELETE"/>

     <input type="submit" value="提交" />

     </form>

     

     修改<br />

      <form action="/springMvcTest/testRestfulUrl.do/1" method="post">

     <input type="hidden" name="_method" value="PUT"/>

     <input type="submit" value="提交" />

     </form>

      <br />

     <br />

     <br />

     ${msg}

    </body>

    </html>

    Web.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

     

    <!-- HiddenHttpMethodFilter是spring3.0之后新增的一个过滤器,可以将post请求转为put和delete请求,

    对实现rest风格有了更好的支持 -->

    <filter>

    <filter-name>HiddenHttpMethodFilter</filter-name>

    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>

    </filter>

    <filter-mapping>

    <filter-name>HiddenHttpMethodFilter</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    <filter>

    <filter-name>CharacterEncodingFilter</filter-name>

    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

    <init-param>

    <param-name>encoding</param-name>

    <param-value>utf-8</param-value>

    </init-param>

    </filter>

    <filter-mapping>

    <filter-name>CharacterEncodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

     

    <!-- 配置的方式

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

     

    <!-- 注解的方式-->

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

    </web-app>

     

    Springmvc.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-3.0.xsd

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd"

           default-lazy-init="true">     

     

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀 -->

       <property name="prefix" value="/"/>

       <property name="suffix" value=".jsp"/>

        </bean>

       <mvc:annotation-driven /> <!-- 基于Schema-based XML的配置定义模式 -->

        <context:component-scan base-package="com.yirong.controller.annotation" />

    </beans>

     

     

    详解@RequestParam

    在上面例子的类中添加以下方法:

    @RequestMapping(value="/testRequestParam")

    public String testRequestParam(@RequestParam(value="userName") String userName,

    @RequestParam(value="age",required=true,)Integer age

               //@RequestParam(value="age",required=false,defaultValue="0")int age, Modelmodel) {

    model.addAttribute("msg","Hello World! 你好springmvc注解   requestParam "+userName+" age="+age);

    return "order/list";

    }

     

    List.jsp:在webContent/order/下

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>requestParam</title>

    </head>

    <body>

     <form action="/springMvcTest/testRequestParam" method="post">

     <input type="text" name="userName" />

     <input type="text" name="age" />

     <input type="submit" value="提交" />

     </form>

     ${msg }

    </body>

    </html>

     

    :@RequestParam(value="age",required=true)value表示为参数名称,在form表单中需要一一对应.

    Required=true表示此参数是必须的,如果不写或把值改为false表示该参数不是必须的,但是要注意:如果是一个Integer类型的值,也就是数字,那么在这里接收参数的类型一定要是Integer对象,不能是int类型,否则当此参数被用到时而又并未给相应的值(当此参数不是必须时),那么就会出现异常

     

    如果一定需要传递int类型,那么需要添加一个配置:@RequestParam(value="age",required=false,defaultValue="0")int age

    表示默认值为0,如果没有传递age,那么默认为0.

     

    了解@RequestHeader

    此注解与详解@RequestMapping的headers参数是一个意思,用法与@RequestMapping相同,表示指定请求头包含指定参数名.了解即可.

     

     

    详解@CookieValue

    此注解可以让处理方法的入参绑定某个Cookies的值,表示是从cookies中取指定参数名称的值.

    每一次请求都有一个JSESSIONID,那么我们可以通过@CookiesValue这个注解将JSESSIONID通过处理方法入参的方式获得

     

    @RequestMapping(value="/testCookiesValue")

    public String testCookiesValue(@CookieValue(value="JSESSIONID") String sessionId,

    @RequestParam(value="age") Integerage, Model model) {

    model.addAttribute("msg","Hello World! 你好springmvc注解   @CookieValue "+sessionId+" age="+age);

    return "order/list";

    }

     

    Cookies.jsp:在webcontent/order/下

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>requestParam</title>

    </head>

    <body>

     <form action="/springMvcTest/testCookiesValue" method="post"> 

     <input type="text" name="age" />

     <input type="submit" value="提交" />

     </form>

     ${msg }

    </body>

    </html>

    效果:正常的取到cookies中的值

     

     

    详解将Pojo做为参数传递

    在前面已实现将对象做为参数传递到spring mvc的controller中,在传递的过程中,spring mvc

    会将指定的参数名自匹配到pojo的属性名中,并且还会填充值到pojo的属性中.且支持级联属性.

     

    案例1:

    :controller中@RequestMapping的写法,在类上有注解,在方法上也有注解,并且处理的方法中的参数为Model model 这是对应的,不能错写.

    :Model model可以去掉不要,即类和方法同时有@RequestMapping注解那么处理方法可添加Model model可不添加,但不能添加ModelMap做为视图数据封装类

     

    OrderController:

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.web.bind.annotation.RequestMapping;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController {

    @RequestMapping("/add")//请求此方法

    public String add(Orderorder,Model model) {

    System.out.println(order.toString());

    model.addAttribute("msg","添加订单成功 "+order.toString());

    return "wel";//视图的名称wel.jsp页面只是一个成功页面,内容为”成功页面”

    } 

    }

    Order.java

    package com.yirong.controller.annotation;

     

    public class Order {

    private StringorderName;

    private Integernumber;

    private Useruser;

     

    public String getOrderName() {

    return orderName;

    }

     

    public void setOrderName(StringorderName) {

    this.orderName =orderName;

    }

     

    public Integer getNumber() {

    return number;

    }

     

    public void setNumber(Integernumber) {

    this.number =number;

    }

     

    public User getUser() {

    return user;

    }

     

    public void setUser(Useruser) {

    this.user =user;

    }

     

    @Override

    public String toString() {

    return "Order [orderName=" +orderName + ", number=" + number + ", user=" +user + "]";

    }

     

    }

     

     

    User.java

    package com.yirong.controller.annotation;

     

    public class User {

    private Stringname;

    private Integerage;

    private Stringtel;

     

    public String getName() {

    return name;

    }

    public void setName(Stringname) {

    this.name =name;

    }

    public Integer getAge() {

    return age;

    }

    public void setAge(Integerage) {

    this.age =age;

    }

    public String getTel() {

    return tel;

    }

    public void setTel(Stringtel) {

    this.tel =tel;

    }

    @Override

    public String toString() {

    return "User [name=" +name + ", age=" + age +", tel=" + tel + "]";

    }

    }

     

     

    addOrder.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    添加订单:<br />

     <form action="/springMvcTest/order/add" method="post">

     订单名称:<input type="text" name="orderName" /><br />

     数量:<input type="text" name="number" /><br />

     用户名:<input type="text" name="user.name" /><br />

     年龄:<input type="text" name="user.age" /><br />

     电话:<input type="text" name="user.tel" /><br />

     <input type="submit" value="提交" /><br />

     </form>

     <br />

    </body>

    </html>

     

    案例2:

    :controller中@RequestMapping的写法,只在方法上也有注解,并且处理的方法中的参数为ModelMap modelMap这是对应的,不能错写.

    :ModelMap modelMap可以去掉不要,即只方法有@RequestMapping注解那么处理方法可添加ModelMap modelMap可不添加,但不能添加Model做为视图数据封装类

    Order2Controller:

    package com.yirong.controller.annotation;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.ui.ModelMap;

    import org.springframework.web.bind.annotation.RequestMapping;

     

    @Controller //表示这个是一个Controller

    public class Order2Controller {

     

    @RequestMapping("/order2")//请求此方法

    public String order2(Orderorder,ModelMap modelMap) {

    System.out.println(order.toString());

    modelMap.addAttribute("msg","添加订单成功  "+order.toString());

    return "wel";//视图的名称wel.jsp页面只是一个成功页面,内容为”成功页面”

    }  

    }

     

     

    Order.java和User.java参考案例1

     

    addOrder.jsp:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    添加订单2:<br />

     <form action="/springMvcTest/order2" method="post">

     订单名称:<input type="text" name="orderName" /><br />

     数量:<input type="text" name="number" /><br />

     用户名:<input type="text" name="user.name" /><br />

     年龄:<input type="text" name="user.age" /><br />

     电话:<input type="text" name="user.tel" /><br />

     <input type="submit" value="提交" /><br />

     </form>

    </body>

    </html>

     

    详解spring mvc接收servlet原生api参数

    Spring mvc的Handler方法可以接受Servlet api的以下类型做为参数:

    HttpServletRequest

    HttpServletResponse

    HttpSession

    java.security.Principal

    Locale

    InputStream

    OutputStream

    Reader

    Writer

     

     

    :

    添加一个方法到controller中

    @RequestMapping("/servApi")

    public void servApi(HttpServletRequestrequest,HttpServletResponseresponse,Writerout) throws IOException {

    request.setCharacterEncoding("UTF-8");

    System.out.println(request+" , "+response);

    out.write("spring mvc servlet  api");

    //return "wel"; //视图的名称

    }

     

    页面请求:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>servlet  </title>

    </head>

    <body> 

     <a href="/springMvcTest/servApi">servlet 原生api</a>

    </body>

    </html>

     

    效果:

     

     

    详解spring mvc 处理模型数据

    Spring mvc 会将模型数据对象中的数据添加到request对象中

    原码:InternalResourceView.renderMergedOutputModel() -> AbstractView.exposeModelAsRequestAttributes()

    ModelAndView

    ModelAndView是一个视图数据封装器,其包含了视图信息和模型数据信息,在controller处理类返回该对象时,直接new操作即可

    :

    /**

     * ModelAndView 的使用

     * 可以通过new ModelAndView时将视图名称添加到ModelAndView中

     * 也可以通过modelAndView.setViewName("wel");设置

     * @return

     */

    @RequestMapping("testModAndView")

    public ModelAndView testModelAndView(){

    ModelAndView modelAndView =new ModelAndView("wel");

    modelAndView.addObject("time",new Date());

    return modelAndView;

    }

     

    Map和Model

    Map and Model 需要写在controller类的处理类的形参中,以参数的方式处理模型数据,其类型为org.springframework.ui.Model和

    org.springframework.ui.ModelMap或java.util.Map,spring mvc框架在渲染视图时会自动将需要渲染的数据添加到模型中.

    Spring mvc 在调用方法前会创建一个隐含的模型对像作为模型数据的存储容器.如果方法的入参为Map或Model类型时,spring mvc会将隐含模型的引用传递给入参.开发者可以通过入参对象访问到模型中所有的数据,也可以向模型中添加新的数据,以渲染到视图.

    Spring mvc model类关系:

     

     

     

    Controller类中的方法:

    /**

     * spring mvc 的controller类的处理方法的形参可以是一个map,而这个map其实是

     * spring mvc提供的org.springframework.validation.support.BindingAwareModelMap的实例

     * @return

     */

    @RequestMapping("/testMap")

    public String testMap(Map<String,Object>map){

    map.put("msg",Arrays.asList("aa","bb","cc",map.getClass().getName()));

    return "wel";

    }

     

    Wel.jsp

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>springmvc </title>

    </head>

    <body>

    <br>  

    ${msg } 

    </body>

    </html>

     

    Model 与 ModelMap入参的方式处理模型数据在前面章节中已有详细例子.

     

    详解@SessionAttributes

    如需在多个请求之间共享某个模型属性数据,则可以在controller类上添加此注解,@SessionAttribute注解只能添加在类上面

    Spring mvc 会将在模型中对应的属性暂存到HttpSession中.

    @SessionAttributes可以通过指定属性名将相应的值放入session以外,还可以通过模型属性中的对象类型将值放入到session中

    :

    @SessionAttributes(types=User.class) 会将隐含模型中所有类型为User.class的属性和值添加到session中

    @SessionAttributes(value={“username”,”age”}) 会将隐含模型中属性名为username和age的属性和值添加到session中

    @SessionAttributes(types={User.class},value={“username”,”age”})同上意

    1. @SessionAttributes 的Value属性表示是将指定的属性放进session

    2. @SessionAttributes 的Type属性表示是将指定的类型的属性全放进session

    3. @SessionAttributes注解只能添加在类上面

     

     

    package com.yirong.controller.annotation;

     

    import java.util.Arrays;

    import java.util.Date;

    import java.util.Map;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.SessionAttributes;

    import org.springframework.web.servlet.ModelAndView;

     

    @SessionAttributes(value={"user"},types={String.class})

    @Controller

    public class ModelViewController {

    @RequestMapping("/testSessionAttri")

    public String testSessionAttri(Map<String,Object>map){

    User user =new User();

    user.setAge(10);

    user.setName("张三");

    user.setTel("13445678945");

    map.put("user",user);

    map.put("addr","shenzhen");

    return "wel";

    }

    }

     

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>springmvc </title>

    </head>

    <body>

     <br >

    request user: ${requestScope.user } <br >

    session user: ${sessionScope.user } <br >  

    request addr: ${requestScope.addr }<br >

    session addr: ${sessionScope.addr }<br >

    </body>

    </html>

     

    详解@ModelAttribute

    应用场景

    通过一个修改操作来了解ModelAttribute使用场景

     

    解决问题:

    在更新之前应该从数据中根据ID拿出需要修改的数据对象A ,然后将要修改的数据填充到A对象中,那么不需要修改的数据在A对象中本身就存在而且是从数据库中填充的,这样更修后就不存在上所描述的问题.这就是ModelAttribute使用的场景(Struts2中有一个类似功能的拦截器)

    代码:

    package com.yirong.controller.annotation;

     

    import java.util.Arrays;

    import java.util.Date;

    import java.util.Map;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.ModelAttribute;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam; 

    import org.springframework.web.servlet.ModelAndView;

     

    //@SessionAttributes(value={"user"},types={String.class}) 注意这个要删除,否则有500 后面章节讲解

    @Controller

    public class ModelViewController {

     

    @RequestMapping("/testModelAttribute")

    //public String testModelAttribute(@ModelAttribute(“user”)Useruser) {

    public String testModelAttribute(Useruser) {

    System.out.println(user.toString());

    return "wel";

    }

    /**

     * 有@ModelAttribute标记的方法,会在每个目标方法执行之前被spring mvc框架调用

     * @param id

     * @param map

     */

    @ModelAttribute

     //不加此注解,在页面输入新数据点修改后,testModelAttribute方法打应的对象中tel的值为null

    public void getUser(@RequestParam(value="id",required=false) Integer id

    ,Map<String,Object> map){

    if (null != id) {

    User user = new User();

    user.setName("zhangsan");

    user.setAge(12);

    user.setTel("13400000000");

    System.out.println("模拟从数据库中取数据完成  "+user.toString());

    map.put("user", user);

    }

    }

    }

     

    test.jsp页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>springmvc </title>

    </head>

    <body>

    <br />

     模拟修改操作:<br />

    原始数据:id : 1 name :zhangsan age: 12tel:13400000000<br />

    修改后的值为: id : 1  name:lisi age:20 tel不修改<br />

    <br />

    <form action="/springMvcTest/testModelAttribute">

    <input type="hidden" name="id" value="1" />

    名称:<input type="text" name="name" value="zhangsan"/><br />

    年龄<input type="text" name="age" value="12"/><br />

    <input type="submit"  value="修改" />

    </form>

    </body>

    </html>

     

    效果:

     

     

     

    原理

    根据上面例子,简单运行流程:

    1. 并在执行testModelAttribute方法之前,执行@ModelAttribute注解的方法getUser,把获取的对象放进Map中,key为user

    2. Spring mvcww map中取出user对象,并把表单中的数据封装到对象中的相应属性

    3. 再执行testModelAttribute方法(也就是目标方法)

    :@ModelAttribute注解的方法中将对象放入到map时,key需要和目标方法的入参的类型首字母小写后的字符串相同

    上例: testModelAttribute方法的入参类型是User,那么首字母小写后为user,则在@ModelAttribute注解的方法中的map设置值时的key也需要为user

     

     走原码:在以下几个关键点打断点,然后观察map中对象的值的变化,可以看到封装流程

    HandlerMethodInvoker

    1. ->invokeHandlerMethod():

     

    : 

    ExtendedModelMap implicitModel) throws Exception {

     

    2.  ->resolveModelAttribute():

     

    3. ->resolveHandlerArguments():

     

    :

     

    再到:AbstractBindingResult->getModel()

     

    原码原理:

    1. 调用@ModelAttribute注解的方法后,把@ModelAttribute方法中的Map中的数据放在了implicitModel中.

    2. 解析请求处理器的目标参数,数据来自WebDataBinder对象的target属性

    a) 创建WebDataBinder对象,

    b) 获得objectName属性:若attrName属性值为””,则objectName为类名第一个字母小写

    i. 若目标方法的入参的Pojo使用了@ModelAttribute来修饰,那么attrName的值就为@ModelAttribute(value指定的值)

    c) 获得target属性

    i. implicitModel中查找attrName对应的属性值,若存在直接取

    ii. 不存在,则验证当前Controller是否使用了@SessionAttributes注解,如用了则从session中取attrName所对应属性的值,如取不到则抛异常

    iii. 如果没有用@SessionAttributes注解或@SessionAttributes中使用value的值指定的key和attrName不相匹配,那么通过反射创建pojo对象进行处理

     

      

    3. Spring mvc 把表单的请求参数赋给了webDataBinder的target对应的属性,再将attrName和target赋给implicitModel,最后将对象(target)传给目标方法入参

     

     

    Spring mvc 确定目标方法pojo类型入参的过程

    1. Spring mvc框架在获取目标方法的参数时,首先判断入参的POJO是否有用@ModelAttribute注解,如果没有,则直接使用POJO的首字母小写后的字符串做为KEY

    如果有使用则直接用@ModelAttribute注解的value的值做为KEY

    2. 使用时在implicitModel中查找key对应的对象,存在就则为入参传入,如找不到key则则检查当前的Handler是否使用了@SessionAttributes注解,如果用了,且能在session中找到相应的key,则从session中取key,否则抛异常.如果没有用或用了但没有包含相应的KEY,则会通过反射POJO来处理

    3. Spring mvc把key和pojo类型的对象保存到imlicitModel中,再保存到request中

     

     

    最终得出@ModelAttribute注解的特点:

    1. @ModelAttribute注解的方法会在每个目标方法执行之前被spring mvc调用

    2. @ModelAttribute注解也可以用来修饰目标方法的POJO类型的入参,其value属性值有以下作用:

    a) Spring mvc 会相济 value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中.

    b) Spring mvc 会以 注解的value的值做为 key ,POJO做为value的方式存入到request中

     

    @SessionAttributes与@ModelAttribute同用时的异常

    根据以上原理分析,注解了@ModelAttribute时,当controller中没明确了标识了所需的key时,而又同时使用了@SessionAttributes注解,那么就会到session中去找@ModelAttribute所标识的key的值或因为默认的值与@SessionAttributes注解的key相同时,那么就可能会发生异常.

    解决办法,@ModelAttribute注解value的值与@SessionAttributes注解的value的值不要相同,或如果没必要则不要随便注解@SessionAttributes

     

    doDispatch

     

    processDispatchResult

     

     

     

    Render

     

     

     

     

     

     

    注解详说:

    http://www.cnblogs.com/xiepeixing/p/4243288.html

     

     

    InternalResourceViewResolver

     

    1. 若项目中使用了jstl,则spring mvc会自动把视图由InternalResourceView转为JstlView

    2. 如果使用了jstl的fmt标签则需要在spring mvc的配置文件中配置国际化资源文件

    <bean id="messageSource"  class="org.springframework.context.support.ResourceBundleMessageSource">

        <property name="basename" value="i18n"></property>

    </bean>

    3. 如果希望直接响应通过spring mvc渲染的页面,可以使用<mvc:view-controller>标签来实现

    <mvc:view-controller

    path="/springMvcTest/testJstlView" view-name="wel" />

     

     

    <mvc:view-controller>

    用于配置直接转发的页面,不需要经过controller,直接输入配置的/aa就会请求到wel视图

    <mvc:view-controller

    path="/aa"view-name="wel" /> 

     

    这样的请求方式适用于,有些页面不需要任何controller处理逻辑就要响应的页面

    :如果需要用<mvc:view-controller>,那么一定要加上<mvc:annotation-driven />,否则除<mvc:view-controller>配置有效外,其他的url都为404

     

    Spring mvc处理静态资源

    优雅的rest风格的资源url不希望带.html或.do等后缀,所以在web.xml中配置DispatcherServlet过滤请求时配置的是/,则spring mvc在捕获web容器的所有请求,包括静态资源的请求,如:js时也会将它们当成一个普通的请求处理,因此将不能在controller中找到请求而报404

    解决问题:

    spring mvc的配置文件中添加一个<mvc:default-servlet-handler />

    原理:

    <mvc:default-servlet-handler />将在spring mvc 上下文中定义一个DefaultServletHttpRequestHandler它会对进入DispatcherServlet的请求进行筛查,如果是没有经过映射的请就将该请求交给web应用服务器默认的servlet处理,如果不是静态资源就由DispatcherServlet处理.

    :一般web应用服务器默认的servlet的名称都是default,如使用的web服务器的默认servlet名称不是default,则需要通过default-servlet-name属性显示的指定:

    <mvc:default-servlet-handler default-servlet-name="servlet名称" />

     

     

    Spring mvc 的标签库

    Spring mvc没有提供循环的标签,所以如果需要的话还需要使用原生的jstl的c标签

    但是spring mvc提供了form标签:

    <%@ taglib uri="http://www.springframework.org/tags/form"prefix="form"%>

    Form标签可以快速的编写表单页面,并能方便的进行表单数据回显,

    :(spring mvc默认是认为表单是一定需要回显的)可以通过form表示的modelAttribute属性来绑定属性模型,

    如果没有绑定,spring mvc默认从request域对象中读取command的表单bean,如果该属性值不存在,则发生异常.

    所以modelAttribute属性在表单上不能少,并且需要绑定一个bean,而在表单中的标签的name就是这个bean的属性名称

    Java代码:

    @RequestMapping("/add")

    public String testSessionAttri(Map<String, Object>map) {

    map.put("user",user);

    return "wel";

    }

     

    <form:form action="add" method="post" modelAttribute="数据回显的对象名user">

    <form:input path="实体属性名"/>

    <form:radiobuttons path="sex"  items="${sexMap }"/>

    <form:checkbox path="" />

    <form:select path=""  items="下拉的对象" 

    itemLabel="下拉的对象名称属性,用于显示" itemValue="选中后获取的值"></form:select>

    </form:form>

    作业:

    spring mvc ,mysql jsp,jstl,实现一个模块的CRUD,用 restful风格

    :spring mvc在删除的时候需要用post请求方式,因为url默认是get请求,所以需要模拟一个post提交方式,需要借助jquery:

    <script type="text/javascript" src="jquery.2.1.js"></script> 

    <script>

    $(function (){

    $("#delBtn").click(function (){

    var href =  $(this).attr("href");

    $("#delFormId").attr("action",href).submit();

    return false;

    });

    });

    </script>

    <form id="delFormId" action="" method="Post">

    <input type="hidden" name="_method" value="DELETE">

    </form>

    <a href="/del/${id}" id="delBtn">删除</a>

     

    mvc:annotation-driven

    <mvc:annotation-driven />会自动注册RequestMappingHandlerMapping,RequestMappingHandlerAdapterExceptionHandlerExceptionResolver三个bean

    还提供以下支持:

    支持使用ConversionService实例对表单参数进行类型转换

    支持使用@NumberFormatannotation.@DateTimeFormat注解完成数据类型的格式化

    支持使用@Valid注解对javabean实例进行jsr 303验证

    支持使用@RequestBody和@ResponseBody注解

    @InitBinder

    @InitBinder注释的方法可以对WebDataBinder对象进行初始化,WebDataBinder是DataBinder的子类,用于完成表单字段到javaBean属性的绑定

    @InitBinder注释的方法不能有返回值,必须是void的

    @InitBinder注释的方法的参数通常是WebDataBinder

    @InitBinder

    public void initBinder(WebDataBinderdataBinder){

    dataBinder.setAllowedFields("name");

    }

    使用场景:当添加订单时,表单有一个字段是选择商品,商品是可以选多个的那么这时往往是选中了商品的ID传往后台,而如果是集合或是对像,那么这个时候框架是无法完成在页面选择的是一个ID,

    而在后台需要装一个集合或对象的转换的,那么就需要手动转换,那么就用到了@InitBinder注释,表示告诉框架忽略指定字段的转载.

    数据格式化和格式化异常消息提示

    配置文件复制”spring mvc 注解开发第4点的配置文件”

    在前面的例子中的user 类中添加以下 属性:

    @DateTimeFormat用于标注在实体类的日期字段上,指定日期的格式,如不标记数据无法获取

    @DateTimeFormat(pattern="yyyy-MM-dd")

    private Datebirth;

     

    public Date getBirth() {

    return birth;

    }

    public void setBirth(Datebirth) {

    this.birth =birth;

    }

    在前面的例子中的 order类中添加以下 属性:

     

    @NumberFormat用于标注在实体类的浮点字段上,指定浮点的格式,如不标记数据无法获取

    @NumberFormat(pattern="#,###,###.#")

    private Floatprice;

    public Float getPrice() {

    return price;

    }

    public void setPrice(Float price) {

    this.price =price;

    }

     

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

     添加订单:<br />

     <form action="/springMvcTest/order/add" method="post">

     订单名称:<input type="text" name="orderName" /><br />

     数量:<input type="text" name="number" /><br />

         价格:<input type="text" name="price"/><br />

     用户名:<input type="text" name="user.name" /><br />

     年龄:<input type="text" name="user.age" /><br />

     电话:<input type="text" name="user.tel" /><br />

     生日:<input type="text" name="user.birth" /><br />

     <input type="submit" value="提交" /><br />

     </form>

     <br />

    </body>

    </html>

    Controller

    @RequestMapping("/add")//请求此方法

    public String add(Orderorder,BindingResult bindResult,Modelmodel) {

    if (bindResult.getErrorCount() > 0){

    System.out.println("转换出错");

    for (FieldErrorerror:bindResult.getFieldErrors()){

    System.out.println(error.getField()+" : "+error.getDefaultMessage());

    }

    }

    System.out.println(order.toString());

    model.addAttribute("msg","添加订单成功 "+order.toString());

    return "wel";//视图的名称

    }

     

    结果:

    转换出错

    price : Failed to convert property value of type [java.lang.String] to required type [java.lang.Float] for property 'price'; nested exception isjava.lang.NumberFormatException: For input string: "a"

    user.birth : Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property 'user.birth'; nested exception isorg.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat java.util.Date] for value 's'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [s]

    Order [orderName=1, number=1, user=User [id=null, name=1, age=13, tel=1, birth=null]]

     

    Order order,BindingResult bindResult

    BindingResult 是框架提供的封装错误信息的处理类,做为参数放在controller类中的处理方法上,并且一定要与实体类参数挨着,

    原理:

     

     

     

     

     

    自定义类型转换器

    添加类型转换器:

    package com.yirong.controller.annotation;

     

    import org.springframework.core.convert.converter.Converter;

    import org.springframework.stereotype.Component;

     

    @Component

    public class OrderConverterimplements Converter<String,Order>{

     @Override

    public Order convert(Stringsource) {

    //逻辑内容,将页面获取的内容封装到order对象中,再把对象返回回去,那么在controller得到的对象就有值

    Order order =new Order();

    if (null !=source) {

    System.out.println(source);

    order.setOrderName(source);

    }

    return order;

    }

    }

     

     

    Controller

    package com.yirong.controller.annotation;

     

    import java.io.IOException;

    import java.io.Writer;

     

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.validation.BindingResult;

    import org.springframework.validation.FieldError;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController {

    @RequestMapping("/addConverter")//请求此方法

    public String add1(@RequestParam("order") Orderorder,Modelmodel ) { 

    System.out.println(order.toString()); 

    model.addAttribute("msg","添加订单成功 "+order.toString());

    return "wel";//视图的名称

    }

    }

     

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    添加订单1:<br />

     <form action="/springMvcTest/order/addConverter" method="post">

     订单名称:<input type="text" name="order" /><br />

     <input type="submit" value="提交" /><br />

     </form>

    </body>

    </html>

     

    配置文件:

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

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd"

           default-lazy-init="true"> 

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass"value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀 -->

       <property name="prefix" value="/"/>

       <property name="suffix"value=".jsp"/>

        </bean>    

     <mvc:annotation-driven conversion-service="orderConverterId" />

         <mvc:default-servlet-handler/>

     <bean id="orderConverterId"  class="org.springframework.context.support.ConversionServiceFactoryBean">

        <property name="converters">

        <set>

        <ref bean="orderConverter"/> <!--以应转换器的类名,首字母小写-->

        </set>

        </property>

    </bean>

    </beans>

     

    JSR 303(数据效验)

     

     

     

     

     

     

    添加jsr 303支持jar包

    hibernate-validator-5.4.0.Final.jar

    hibernate-validator-annotation-processor-5.4.0.Final.jar

    classmate-1.3.1.jar

    jboss-logging-3.3.0.Final.jar

    validation-api-1.1.0.Final.jar

     

    添加配置文件

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

    http://www.springframework.org/schema/mvc

    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd

            http://www.springframework.org/schema/context

            http://www.springframework.org/schema/context/spring-context.xsd"

           default-lazy-init="true">     

     

    <!-- 配置页面渲染器 -->

    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

       <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>

       <!-- 配置结果视图的前缀和后缀 -->

       <property name="prefix" value="/"/>

       <property name="suffix" value=".jsp"/>

        </bean>

        

        <bean id="messageSource"  class="org.springframework.context.support.ResourceBundleMessageSource">

        <property name="basename" value="i18n"></property>

    </bean>

     

       <mvc:annotation-driven   />  <!-- 基于Schema-based XML的配置定义模式 -->

        <context:component-scan base-package="com.yirong.controller" />

        <mvc:default-servlet-handler/>

    </beans>

     

     

    User:

    package com.yirong.controller.annotation;

     

    import java.util.Date;

     

    import javax.validation.constraints.Past;

    import javax.validation.constraints.Size;

     

    import org.hibernate.validator.constraints.Email;

    import org.hibernate.validator.constraints.NotEmpty;

    import org.springframework.format.annotation.DateTimeFormat;

     

    public class User {

    private Integerid;

    @NotEmpty

    private String name;

    private Integerage;

    private String tel;

    @Email(message="邮箱格式错误")

    private String email;

    @Past //生日应该是一个之前的时间 ,past就表示是之前

    @DateTimeFormat(pattern ="yyyy-MM-dd")

    private Datebirth;

    public Integer getId() {

    return id;

    }

    public void setId(Integerid) {

    this.id =id;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name =name;

    }

    public Integer getAge() {

    return age;

    }

    public void setAge(Integerage) {

    this.age =age;

    }

    public String getTel() {

    return tel;

    }

    public void setTel(String tel) {

    this.tel =tel;

    }

    public String getEmail() {

    return email;

    }

    public void setEmail(String email) {

    this.email =email;

    }

    public Date getBirth() {

    return birth;

    }

    public void setBirth(Datebirth) {

    this.birth =birth;

    }

    @Override

    public String toString() {

    return "User [id=" +id + ", name=" +name + ", age=" + age +", tel=" + tel + ", email=" +email + ", birth="

    + birth +"]";

    }

    }

     

     

    Controller

    package com.yirong.controller.annotation;

     

    import java.io.IOException;

    import java.io.Writer;

     

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.validation.Valid;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.ui.Model;

    import org.springframework.validation.BindingResult;

    import org.springframework.validation.FieldError;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    @RequestMapping("user")

    @Controller //表示这个是一个Controller

    public class OrderController {

    @RequestMapping("/addUser")//请求此方法

    public String add(@Valid Useruser,BindingResultbindResult,Modelmodel) {

    if (bindResult.getErrorCount() > 0){

    System.out.println("验证异常");

    for (FieldErrorerror:bindResult.getFieldErrors()){

    System.out.println(error.getField()+" : "+error.getDefaultMessage());

    }

    }

    System.out.println(user.toString());

    return "wel";//视图的名称

    }

    }

     

    页面

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    添加用户 jsr 303:<br />

     <form action="/springMvcTest/user/addUser" method="post">

     名称:<input type="text" name="name" /><br />

     年龄:<input type="text" name="age" /><br />

     电话:<input type="text" name="tel" /><br />

     生日:<input type="text" name="birth" /><br />

     email:<input type="text" name="email" /><br />

     <input type="submit" value="提交" /><br />

     </form><br /><br />

    </body>

    </html>

     

    效果:

    验证异常

    email : 邮箱格式错误

    name : 不能为空

    birth : 需要是一个过去的时间

    User [id=null, name=, age=1, tel=1, email=a, birth=Tue Oct 10 00:00:00 CST 2017]

     

    Json

    Spring mvc对json也有很好的支持,需要下载jar

    Jackson下载   http://wiki.fasterxml.com/JacksonDownload

    导入jar包

    jackson-annotations-2.8.0.jar

    jackson-core-2.8.1.jar

    jackson-databind-2.8.5.jar

     

    配置文件复制”spring mvc 注解开发第4点的配置文件”

    页面

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body>

    <script type="text/javascript" src="../jquery-1.10.2.js" ></script>

    <script type="text/javascript">

    $(function(){

    $('#testJsonId').click(function (){

    $.post("/springMvcTest/order/testJson",{

                     },function(data){

      console.log(data);

    });

    });

    });

    </script>

    <br />

    testjson:

    <button id="testJsonId">testjson</button>

    <br />

    </body>

    </html>

     

    Controlller

    package com.yirong.controller.annotation;

     

    import java.io.IOException;

    import java.io.Writer;

    import java.util.ArrayList;

    import java.util.List;

     

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.validation.Valid;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.ResponseBody;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController {

    @ResponseBody

    @RequestMapping("/testJson")//请求此方法

    public List<Order> testJson() {

    List<Order> list =new ArrayList<>();

    Order o =new Order();

    o.setOrderName("a");

    Order o2 =new Order();

    o2.setOrderName("b");

    list.add(o);

    list.add(o2);

    return list; 

    }

    }

     

    效果:

    两个对象的值,正常拿到了

     

    HttpMessageConverter<T>

    HttpMessageConverter会将spring mvc框架的返回结果以out对象输出到客户端,只需要加上@responseBody的注解即可自动的用HttpMessageConverter进行转换处理

     

     


     

     

     

     

     

    HttpMessageConverter的@ResponseBody文件上传

    Controller

    import org.springframework.web.bind.annotation.RequestBody;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.bind.annotation.ResponseBody;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController {

    @ResponseBody

    @RequestMapping("/testh")

    public String testh(@RequestBodyString body){

    System.out.println(body);

    return "aa";

    }

    }

     

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body> 

    <br />

    文件上传:

    <form action="/springMvcTest/order/testh" method="POST" enctype="multipart/form-data" >

    file:<input type="file" name="file" /><br />

    desc:<input type="text" name="desc" /><br />

    <input type="submit" value="submit"/>

    </form>

    <br />

    </body>

    </html>

     

    运行结果:

     

     

    响应到页面的文字:

     

     

    文件下载

     

    webContent/files/下放一个文件abc.txt,模拟文件下载

    Controller

     

     

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <html>

    <head>

    <title>restful</title>

    </head>

    <body> 

    <br />

    文件下载:

     <a href=”testResponseEntity”>test 文件下载</a>

    <br />

    </body>

    </html>

     

     

    自己写

    文件上传和下载

    package com.yirong.annoation;

     

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.InputStreamReader;

     

    import javax.servlet.ServletContext;

    import javax.servlet.http.HttpSession;

     

    import org.springframework.http.HttpHeaders;

    import org.springframework.http.HttpStatus;

    import org.springframework.http.ResponseEntity;

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.multipart.MultipartFile;

     

    @Controller

    @RequestMapping("/jsr")

    public class File {

     

    /**

     * 文件上传

     * @param desc

     * @param file

     * @return

     */

    @RequestMapping("/uploadFile")

    public String uploadFile(@RequestParam("desc") String desc,@RequestParam("file") MultipartFilefile){

    System.out.println("文件描述:"+desc);

    System.out.println("文件名称:"+file.getOriginalFilename());

    try {

    InputStream input =file.getInputStream();

    BufferedReader buff =new BufferedReader(new InputStreamReader(input));

    String str;

    System.out.println("文件内容如下:");

    while((str =buff.readLine()) !=null){

    System.out.println(str);

    }

    } catch (IOExceptione) {

    e.printStackTrace();

    }

    return "jsr/list";

    }

    /**

     * 文件下载

     * @param session

     * @return

     * @throws IOException

     */

    @RequestMapping("/testResponseEntity")

    public ResponseEntity<byte[]> restResponseEntity(HttpSessionsession,StringfileName) throws IOException{

    byte[]body=null;

    String name =new String(fileName.getBytes("iso-8859-1"),"utf-8");

    ServletContext context=session.getServletContext();

    System.out.println(name);

    InputStream in=context.getResourceAsStream("/file/"+name);

    body=new byte[in.available()];

    in.read(body);

    HttpHeaders headers=new HttpHeaders();

    headers.add("Content-Disposition","attachment;filename="+new String(name.getBytes(),"iso-8859-1"));

    HttpStatus status=HttpStatus.OK;

    ResponseEntity<byte[]>response=new ResponseEntity<byte[]>(body,headers,status);

    return response;

    }

    }

     

    页面:

        文件上传:

        <form action="<%=request.getContextPath()%>/jsr/uploadFile" method="POST" enctype="multipart/form-data" >

    file:<input type="file" name="file" /><br />

    desc:<input type="text" name="desc" /><br />

    <input type="submit" value="submit"/>

    </form>

        <hr>

         <a href="<%=request.getContextPath()%>/jsr/testResponseEntity?fileName=罗.txt">文件下载</a><br/>  要下载的文件必须放置在Webcontent下

         <a href="<%=request.getContextPath()%>/jsr/testResponseEntity?fileName=弦子-天真.mp3">弦子 -天真.mp3</a>

         <br/>

         <hr>

     

    package com.yirong.annoation;

    import java.io.BufferedInputStream;

    import java.io.BufferedOutputStream;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.IOException;

     

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.multipart.MultipartFile;

    import org.springframework.web.servlet.ModelAndView;

     

    @Controller

    public class FileUploadController {

     

    /*

     * SpringMVC中的文件上传

     * @第一步:由于SpringMVC使用的是commons-fileupload实现,故将其组件引入项目中

     * @这里用到的是commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar

     * @第二步:spring-mvc中配置MultipartResolver处理器。可在此加入对上传文件的属性限制

     *  <bean id="multipartResolver"  

     *  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

     * <!-- 设置上传文件的最大尺寸为10MB -->  

     *<property name="maxUploadSize">  

     *<value>10000000</value>  

     * </property>  

     * </bean>

     * 第三步:在Controller的方法中添加MultipartFile参数。该参数用于接收表单中file组件的内容

     *第四步:编写前台表单。注意enctype="multipart/form-data"以及<input type="file" name="****"/>

     *  如果是单个文件 直接使用MultipartFile 即可

     */ 

    @RequestMapping("/upload")

    public ModelAndView upload(Stringname,

    //上传多个文件

    @RequestParam("file") MultipartFile[]file,

    HttpServletRequest request)throws IllegalStateException,IOException {

    //获取文件 存储位置

    String realPath =request.getSession().getServletContext().getRealPath("/uploadFile");

    File pathFile =new File(realPath);

    if (!pathFile.exists()) {

    //文件夹不存 创建文件

    pathFile.mkdirs();

    }

    for (MultipartFilef : file) {

    System.out.println("文件类型:"+f.getContentType());

    System.out.println("文件名称:"+f.getOriginalFilename());

    System.out.println("文件大小:"+f.getSize());

    System.out.println(".................................................");

    //将文件copy上传到服务器

    f.transferTo(new File(realPath +"/" + f.getOriginalFilename()));

     //FileUtils.copy

    }

    //获取modelandview对象

    ModelAndView view =new ModelAndView();

    view.setViewName("redirect:index.jsp");

    return view;

    }

    @RequestMapping(value ="download")  

    public ModelAndView download(HttpServletRequestrequest,HttpServletResponseresponse) throws Exception {  

            //String storeName = "Spring3.xAPI_zh.chm";  

    String storeName="房地.txt";

    String contentType ="application/octet-stream";  

    FileUploadController.download(request,response, storeName, contentType);  

    return null;  

    }  

          //文件下载 主要方法

    public static void download(HttpServletRequestrequest, HttpServletResponseresponse,

    String storeName, StringcontentType )throws Exception {  

    request.setCharacterEncoding("UTF-8");  

    BufferedInputStream bis =null;  

    BufferedOutputStream bos =null;  

    //获取项目根目录

    String ctxPath =request.getSession().getServletContext().getRealPath("");  

    //获取下载文件露肩

    String downLoadPath =ctxPath+"/uploadFile/"+storeName;  

    //获取文件的长度

    long fileLength =new File(downLoadPath).length();  

    //设置文件输出类型

    response.setContentType("application/octet-stream");  

    response.setHeader("Content-disposition","attachment; filename="  

    + new String(storeName.getBytes("utf-8"),"ISO8859-1"));

    //设置输出长度

    response.setHeader("Content-Length", String.valueOf(fileLength));  

    //获取输入流

    bis = new BufferedInputStream(new FileInputStream(downLoadPath));  

    //输出流

    bos = new BufferedOutputStream(response.getOutputStream());  

    byte[]buff = new byte[2048];  

    int bytesRead;  

    while (-1 != (bytesRead =bis.read(buff, 0,buff.length))) {  

    bos.write(buff, 0,bytesRead);  

    }  

    //关闭流

    bis.close();  

    bos.close();  

    }  

    }

    国际化

    在配置文件中添加:

     <bean id="messageSource"  class="org.springframework.context.support.ResourceBundleMessageSource">

        <property name="basename" value="i18n"></property>

    </bean>

    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

     

    Controller

    import org.springframework.beans.factory.annotation.Autowired;

    import org.springframework.context.support.ResourceBundleMessageSource;

    import org.springframework.web.bind.annotation.RequestMapping;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController {

       @Autowired

    private ResourceBundleMessageSourcemessageSource;

    @RequestMapping("/testI18n") 

    public String testI18n(Localelocale){

    String val =messageSource.getMessage("i18n.username",null,locale);

    System.out.println(val);

    return "i18n";

    }

    }

     

    添加配置文件i18n_zh_CN.properties到src下( unicode)

    #用户名

    i18n.username=\u7528\u6237\u540D 

    #密码

    i18n.password=\u5BC6\u7801

    i18n_en_US.properties

    i18n.username=username

    i18n.password=password

     

    页面相用fmt

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   

    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  

    <html>

    <head>

    <title>springmvc </title>

    </head>

    <body>

     <fmt:message key="i18n.username"></fmt:message>

     <br />

     

     <a href="/springMvcTest/order/testI18n" >testI18n </a>

      </body>

    </html>

     

    效果:

    当请求testI18n时,打应的就是资源文件中的相应的国际化资源内容

     

     

    :在页面如果需要国际化和数据格式化,则需要用到jstl的fmt标签(spring mvc暂时没有提供标签)

     

    页面中英文切换

    页面:

    <%@ page language="java" contentType="text/html; charset=utf-8"%>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   

    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>  

    <html>

    <head>

    <title>springmvc </title>

    </head>

    <body>

     <fmt:message key="i18n.username"></fmt:message>

     <br />

     

     <a href="/springMvcTest/order/testI18n?locale=zh_CH" >testI18n中文</a>

      <a href="/springMvcTest/order/testI18n?locale=en_US" >testI18n英文</a>

    </body>

    </html>

     

     

    配置文件中添加:

     

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

    <property name="basename" value="i18n"></property>

    </bean>

    <bean id="localeResolver"  class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

     <mvc:interceptors>

    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>

    </mvc:interceptors> 

     

     

    效果:

     

     

     

     

     

     

     

     

     

     

    Spring mvc文件上传2

    导入依赖的jar

    commons-fileupload-1.3.1.jar

    commons-io-2.2.jar

     

    在配置文件中添加:

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

    <property name="defaultEncoding" value="utf-8"></property>

    <property name="maxUploadSize" value="10240"></property>

    </bean>

     

    Controller

    @RequestMapping("/testupload")

    public String testupload(@RequestParam("desc") String desc,

    @RequestParam("file") MultipartFilefile){

    System.out.println(desc);

    System.out.println(file.getOriginalFilename());

    try {

    System.out.println(file.getInputStream());

    } catch (IOExceptione) {

    e.printStackTrace();

    }

    return "wel";

    }

     

     

    页面添加内容

    <br />

    文件上传2:

    <form action="/springMvcTest/order/testupload" method="POST" enctype="multipart/form-data">

    file:<input type="file" name="file" /><br />

    desc:<input type="text" name="desc" /><br />

    <input type="submit" value="submit"/>

    </form>

     

    效果:

     

     

     

    自定义拦截器

    spring mvc 框架中要自定义拦截就要实现HandlerInterceptor:

    package com.yirong.controller.annotation;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import org.springframework.web.servlet.HandlerInterceptor;

    import org.springframework.web.servlet.ModelAndView;

    public class FirstInterceptorimplements HandlerInterceptor{

    /**

     * 此方法会在controller的目标方法调用前被调用 ,如果返回false则拦截器的后面两个方法和目标方法都不会再调用,

          可以做权限,日志,事务等功能

     */

    @Override

    public boolean preHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler)

    throws Exception {

    System.out.println("preHandle ");

    return true; 

    }

        /**

     * 调用目标方法之后,渲染视图之前被调用 可以对视做出更改,或修改请求域

     */

    @Override

    public void postHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler,

    ModelAndView modelAndView)throws Exception {

    System.out.println("postHandle ");

    }

        /**

     * 渲染视图之后被调用  可以做释放资源

     */

    @Override

    public void afterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecthandler, Exceptionex)

    throws Exception {

    System.out.println("afterCompletion ");

    }

    }

     

    在配置文件中添加配置

     

     <mvc:interceptors>

    <!--自定义拦截器 -->

     <bean class="com.yirong.controller.annotation.FirstInterceptor"></bean>

    </mvc:interceptors> 

     

     

    写一个controller这里使用JSR 303的例子来调用一下,

    访问连接:

    http://localhost:8080/springMvcTest/order/addUser

     

    效果:

     

     

    这样拦截器就已经起效果了

     

     

     

     

    指定url 用指定的拦截器

    再创建一个拦截器SecondInterceptor

    <mvc:interceptors>

     <!--自定义拦截器 -->

     <bean class="com.yirong.controller.annotation.FirstInterceptor"></bean>

     <mvc:interceptor> <!--表示/addUser 用拦截器:SecondInterceptor-->

     <mvc:mapping path="/addUser"/>

     <bean class="com.yirong.controller.annotation.SecondInterceptor"></bean>

     </mvc:interceptor> 

    </mvc:interceptors> 

     

    Spring mvc拦截器执行顺序:

     

     

    当后面的拦截器返回false时直接执行前一个拦截器的afterCompletion方法,流程结束

     

    异常处理

    DispatcherServlet会默认装配HandlerExceptionResolver,如果spring mvc中没有配置<mvc:annotation-driven/>配置,那么框架会装载:

    AnnotationMethodHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver

    如果使用了<mvc:annotation-driven/>配置,

    那么框架会装载:ExceptionHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver来处理异常

    重点:ExceptionHandlerExceptionResolver

     

    ExceptionHandlerExceptionResolver主要用@ExceptionHandler注解定义异常处理方法

    @ExceptionHandler定义的异常处理方法有优先级问题,优先使用相对应的异常,如果没有就找抛出的异常的父类,并且不能同时配置多个完全相同的异常处理方法,比如:同时在多个方法标注:@ExceptionHandler({ArrayIndexOutOfBoundsException.class}),或不能同时在多个方法上只标注:@ExceptionHandler

    ,如果ExceptionHandlerExceptionResolver在目标controller中找不到@ExceptionHandler注解定义的方法,那么就会去找用@ControllerAdvice注解的类,并找这个类中的用@ExceptionHandler注解的方法来处理异常

    :如果希望将异常显示到页面去,那么只能用ModelAndView,因为用@ExceptionHandler注解的方法不能用Map作为入参 

     

    Controller

     

    package com.yirong.controller.annotation;

     

    import java.io.IOException;

    import java.io.Writer;

    import java.util.ArrayList;

    import java.util.Date;

    import java.util.List;

    import java.util.Locale;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.validation.Valid;

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.ExceptionHandler;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.servlet.ModelAndView;

    @RequestMapping("order")

    @Controller //表示这个是一个Controller

    public class OrderController { 

    @ExceptionHandler({ArithmeticException.class})

    public ModelAndView handlerException(Exceptionex){

    System.out.println("异常:"+ex);

    ModelAndView mv =new ModelAndView();

    mv.setViewName("error");

    mv.addObject("exception",ex);

    return mv;

    }

    @ExceptionHandler({RuntimeException.class})

    public ModelAndView handlerException1(Exceptionex){

    System.out.println("异常1:"+ex);

    ModelAndView mv =new ModelAndView();

    mv.setViewName("error");

    mv.addObject("exception",ex);

    return mv;

    }  

    @RequestMapping("/testExcep")

    public StringtestExcep(@RequestParam("i") Integeri){

     System.out.println(10/i);

    return "wel";

    }

    }

     

    页面添加一个连接

     <a href="/springMvcTest/order/testExcep?i=10">异常</a>

     

    当请求此连接,给参数为0的时候,就会出现异常,

    出异常的时候,因为有配置@ExceptionHandler,则异常会默认被用此注解的方法去处理

    :@ExceptionHandler可以指定异常的类型,例子中添加了两个异常方法,一个是RuntimeException类型的异常方法,

    一个是ArithmeticException类型的异常方法,那么当testExcep方法出异常后会调用被标注为ArithmeticException异常的方法来处理异常,

     

    如果目标controller中没有异常处理方法,那么怎么处理异常?

    Spring mvc框架提供了一个异常处理方式,可以将异常处理方法写在一个指定类中,这个类需要用@ControllerAdvice注解,目标controller中没有异常处理方法时,就会找用@ControllerAdvice注解的类,并找这个类中的用@ExceptionHandler注解的方法来处理异常

     

     

    package com.yirong.controller.annotation;

     

    import org.springframework.web.bind.annotation.ControllerAdvice;

    import org.springframework.web.bind.annotation.ExceptionHandler;

    import org.springframework.web.servlet.ModelAndView;

     

    @ControllerAdvice

    public class MyExceptionHandler {

     

    @ExceptionHandler({ArithmeticException.class})

    public ModelAndView handlerException(Exceptionex){

    System.out.println("异常:"+ex);

    ModelAndView mv =new ModelAndView();

    mv.setViewName("error");

    mv.addObject("exception",ex);

    return mv;

    }

    @ExceptionHandler({RuntimeException.class})

    public ModelAndView handlerException1(Exceptionex){

    System.out.println("异常1:"+ex);

    ModelAndView mv =new ModelAndView();

    mv.setViewName("error");

    mv.addObject("exception",ex);

    return mv;

    }

    }

     

     

    SimpleMappingExceptionResolver

    了解

    SimpleMappingExceptionResolver异常处理,ex为页面使用的对象在requestScope中

    prop 表示配置发生指定异常去指定页面

    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

    <property name="exceptionAttribute" value="ex"></property>

    <property name="exceptionMappings">

    <props>    

    <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>

    </props>

    </property>

    </bean>

    SpringMVC 数据转换 & 数据格式化 & 数据校验

     

     

    Spring mvc 整合spring

     

    使用注解,那么就需要在配置文件中配置扫描<context:component-scan base-package="指定扫描的包路径" />

    Spring mvc需要配置,而spring的容器也需要配置,也就是配置bean的包.如果这两个配置有重复的话,那么容器将加载多次,这是不对的.

    所以需要配置过滤:

    spring mvc的配置文件中可以配置指定要扫描的包路径下的指定注解,在spring 中可以配置指定路径下不扫描指定注解

    <context:component-scan base-package="com.yr" use-default-filters="false" >

    <context:include-filter type="annotation" 

    expression="org.springframework.stereotype.Controller"/> 

    <context:include-filter type="annotation" 

    expression="org.springframework.web.bind.annotation.ControllerAdvice"/>

    </context:component-scan>

     

    Spring配置文件中:

    <context:component-scan base-package="com.yr" use-default-filters="false" >

    <context:exclude-filter type="annotation" 

    expression="org.springframework.stereotype.Controller"/> 

    <context:exclude-filter type="annotation" 

    expression="org.springframework.web.bind.annotation.ControllerAdvice"/>

    </context:component-scan>

    展开全文
  • SpringMVC是什么?

    万次阅读 多人点赞 2017-05-02 10:23:18
    一,首先是一个MVC框架。 在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,是为了简化开发,减少出错。还是为了组内开发人员...三,springMVC

    一,首先是一个MVC框架。

    在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,是为了简化开发,减少出错。还是为了组内开发人员之间的配合。总之就是一种分层工作的办法。

     

    二,springMVC,是spring的一个子框架,当然拥有spring的特性,如依赖注入。

    三,springMVC的信息流是什么样的?

    首先用户通过HTTP请求到服务器,服务器会根据你的url来将请求转到不同的控制器Controller。这是第一步,具体需要做的是在web.xml中设置URLpattern映射到spring的DispatcherServlet,这是控制器是负责第一道处理,用来转发请求的,它会将请求转发到合适的Controller上。那么问题来了,它是根据什么转发呢?这个问题有些混乱,原因是springMVC一直在升级,不断贡献新的url到Controller的映射方法。但是万变不离其宗,不管如何变,它的目的都不变,就是设法建立url到Controller的映射,找到这个目的之后,看起来就容易一些。具体来看,

    方法1,在springmvc的配置文件中,直接将bean的name写成一个url,如

    <bean name=”/product_input” class="com.ap.ProductInputController" />

    通过这句配置,就直接将/product_input这url的请求转发到了ProductInputController这个类上。

    注:但是这个方法被认为是老套的方法,现在已经不流行了。了解就可以,现在推荐的是注解的方式,即方法2的方式。

     

    方法2,这种方式,在给Controller命名时,就可以无所谓了, 它的映射不是依赖这个名字,所以可以像下面这种方式来写这个bean的配置,可以随便起一个,如

    <bean name=”product” class="com".ap.ProductInputController />

    到这里,显然还是没有实现url到Controller的映射,因为url都还没看见呢,

    现在的springMVC有一个注解是RequestMapping,专门负责映射url的,比方说需要映射到ProductInputController的 addProduct()这个方法,只需要在这个方法上加上一个注解,如

    @RequestMapping(name=”product_input”)

    addProduct()

    通过这个注解,就可以将product_input这个url映射到addProduct这个方法了。是不是很简单。其实做的事情都一样,只不过是换了一种写法和位置。

    感觉好神奇的样子,我一开始也有这种感觉,直到我了解了原始Servlet是如何将url和处理业务的类联系起来的,才发现这个过程也没有那么神秘,这里推荐一本书《SpringMVC学习指南》 Paul Deck著,适合0基础的人看,例子很详细。

    我大概说一下url到Controller是怎么回事:

    起点是,用户通过HTTP请求了服务器,那么一定就有URL,比方说是http://www.dudu.com/getName,其中getName就是我的url,假设你的servlet是部署在tomcat中的,在web.xml这个配置文件中,应该有url到某个类的关系,或者通过别的注解的方法 如@Webservlet(name= “xxController”, urlPatterns = {“product_input”}), 这里意思就是这个url进来后,把请求交给xxController这个class去处理,这个类继承了HttpServlet, 并且重写的doGet方法,你的请求就会来到这个方法里,然后,在方法内调用request.getRequestURI这个方法,拿到了你的url=getName,之后就是字符串匹配equals,调用后面具体的类。

    我们使用框架的原因,就是在开发中,这样的步骤都是重复的,而且每次都一样,所以写框架的人,就把这样套路式的代码封装了, 细节都交给他来处理,我们只要做两件和自己业务相关的事,一个是确定url,二是,这个url指向那个类。写到这里基本把url到Controller这件事说完了。这里有两个类一个是DispatcherServlet,这个是SpringMVC框架自带的,一个就是你自己处理业务的类,比如是ProductController。控制器的命名都喜欢叫XXXController。下面画一张图说明这一步

     

     

    四,MVC,先说的居然是C,Controller,下面说View,就是视图,展示。用户的浏览器,看到的都是比较美观的网页,这就是HTML,它负责来将苦涩的数据,展现成各种样式,让普通用户看起来也不错,而不是一堆JSON数据。用户的请求进来之后,肯定还是要返回给用户页面的,这每个页面就是一个VIEW,view就像一个网页的框架,某个页面的框架是固定的,不同的是其中的数据。比方说购物车页面,就是一个框架。那你的购物车和我的大体看起来是一样的,但其中的具体内容不同,因为买的商品不同,而这具体的东西,或叫做数据,就是Model。现在M和V就有了。

     

    下面再串一个这个流程,刚才说到请求已经到了Controller,这个类的作用就是1,选择适当的view返回给用户,2,组织数据,即生成Model。网络传输和信息技术主要处理的就是数据,而现在数据就放在Model中,或者把放数据的地方叫做Model,比如用户在请求查询用户信息,那么Controller做的就是,在数据库中找到这些信息,然后把信息添加到Model中,然后把Model和对应的View一起返回给DispatcherServlet。 这里继续补充上一张图:

     

     

     

     

     

     

    五,现在DispatcherServlet已经拿到Model里的数据和该用哪个View来展示给用户了。

    所以会将Model和View融合,具体就是用Model的数据把View的变量都换成具体的值,然后view就变成一个HTML的页面了,最后把这个HTML返回给用户,用户那边用浏览器来解释HTML,看到就是正常的网页。 全过程结束。

    展开全文
  • mybatis的xxxMapper.xml文件 通过mybatis与数据库交互时,maven项目中resources文件夹下的xml文件一般对应java/mapper文件夹下的相应xxxMapper类或接口。 在xxxMapper.xml文件中有相应的&...
  • ssm框架实现简单前后台交互

    千次阅读 2018-12-22 09:57:07
    ssm框架实现简单交互 今天简单的测试了下在...ssm(spring-springmvc-mybatis)实现过程可以是如下流程                   来看下各个层的实现代码: 实体层: package com.qcbylearn.en...
  • 前后端交互主要目的 个人觉得,前后端交互的目的无非就是为了实现视图和业务逻辑的转换,前端发出请求,后端根据前端请求进行相应的数据处理然后给出不同响应 先以Servlet为基础的Model工作流程了解一下前后端...
  • 1.在前台jsp页面中一般使用Ajax方法去获取后台数据用于前端使用。$.ajax({url: "<c:url value='/strategy/deleteCelue'/>",//请求的url地址也就是你所需要跳转的controller的方法的地址(仅用参考,...
  • 首先映射生成数据库中表对应的mapper和表名相同的java文件和表名后加个Example的java文件后。再创建一个表名+service和一个页面名+controller 的java文件。 ... (SELECT * FROM dim_warning_index)dim right join...
  • SpringMVC框架理解

    万次阅读 多人点赞 2019-06-30 15:00:07
    Struts和SpringMVC是Web层的框架,Spring是业务层的框架,Hibernate和MyBatis是持久层的框架。 为什么要使用SpringMVC? 很多应用程序的问题在于处理业务数据的对象和显示业务数据的视图之间存在紧密耦合,通常...
  • SpringMVC| Web MVC简介

    万次阅读 2019-07-01 16:53:12
    文章目录1.1、Web开发中的请求-响应模型:1.2、标准MVC模型概述1.3、Web MVC概述1.4、Web端开发发展历程1.4.1、CGI:1.4.2、Servlet:1.4.3、JSP:1.4.4、Model1:1.4.5、Model2:1.4.5、服务到工作者:Front ...
  • SpringMVC

    万次阅读 多人点赞 2018-05-29 00:10:03
    一、SpringMVC简介MVC是我们开发WEB应用程序的通用架构方式MVC的核心思想是业务数据抽取和业务数据呈现相分离。MVC:M(Model)+V(View)+C(Controller)M(模型层):业务数据的信息表示,通常是业务实体V(视...
  • Spring和Spring Mvc整合详解

    千次阅读 2019-08-09 12:44:16
    Spring和Spring Mvc整合详解 官方主页 Spring Spring Mvc 概述 Spring Mvc的启动方式不同于Spring Boot,Spring Boot内嵌了tomcat容器,可以打包成jar文件快速启动。Spring Mvc仍需要打包成war包。...
  • 采用springmvc的好处

    万次阅读 2018-06-07 11:02:54
    采用springmvc的好处  Spring MVC中提供一个DispatcherServlet, 无需额外开发。  springMVC中使用基于xml的配置文件,可以编辑,无需重新编译应用程序。  springMVC实例化控制器,并根据用户输入来构造...
  • springmvc 狂神说的详细笔记

    万次阅读 多人点赞 2020-04-22 14:04:29
    狂神说springmvc 视频链接: B站视频 springmvc 系列笔记 狂神说SpringMVC01: 什么是SpringMVC 狂神说SpringMVC02: 第一个MVC程序 狂神说SpringMVC03: RestFul和控制器 狂神说SpringMVC04: 数据处...
  • 推荐一本好书《精通SpringMVC(第四版)》

    万次阅读 多人点赞 2018-07-09 15:49:05
    链接: https://pan.baidu.com/s/19KbufY0gtMgZRpenCJFXgw 密码: adne
  • spring+springMVC+mybatis 所需jar包

    万次阅读 2014-12-16 17:04:09
    spring+springMVC+mybatis 所需jar包spring+springMVC+mybatis 所需jar包spring+springMVC+mybatis 所需jar包
  • Struts2和springmvc的本质区别:

    万次阅读 2017-12-19 20:10:23
    1.springmvc入口是一个servlet前端控制器(DispatcherServlet),struts2入口是一filter过滤器(StrutsPrepareAndExecuteFilter).  2.struts2通过在action类中定义成员变量接收参数,(属性驱动和模型驱动),它只能使用多...
  • 全网第一套基于Spring4.x、涵盖所有企业开发技术点、源码级讲授的 SpringMVC视频。  本套视频涵盖 SpringMVC 开发过程中所有的技术问题,多个技术点更是从源代码级别进行分析,授之以渔。学习本套视频后,你会真正...
1 2 3 4 5 ... 20
收藏数 241,570
精华内容 96,628
关键字:

springmvc