五:Day09_SpringMVC01

一、Sping MVC的介绍

1. 使用Front(前端)设计模式改写代码

1.1 目前的写法

目前我们所写的项目,持久层、业务层的类都放入到Spring容器之中了。他们之间需要注入非常方便,只需要通过@Autowired注解即可。

但是由于Servlet整个生命周期都是被Tomcat进行管理的,一个功能对应一个Servlet并且无法把Servlet放入到Spring容器中。所以每次编写Servlet时都需要编写init方法先获取到Spring容器,然后从Spring容器中取出需要使用的Bean。

1.2 使用Front设计模式

Front(前端)设计模式就是有一个前端(不是前端专业那个前端,是最前面的意思)统一入口,在统一入口根据请求url调用自己的编写的普通方法。

 五:Day09_SpringMVC01_第1张图片

新建com.bjsxt.controller.EmpController。

// 这个类是自定义的普通类,所以可以放入到Spring容器中
// 因为这个类是控制层代码,所以用@Controller注解
@Controller
public class EmpController {
    // 当前类已经放入到了Spring容器,所以可以自动注入
    @Autowired
    private EmpService empService;

    public void delete(){
        // 删除员工的代码
    }

    public void show(){
        // 显示员工信息的代码
    }
}

新建com.bjsxt.controller.MyServlet。

这个Servlet就是Front设计模式中的前端。是请求的统一入口。

// 在Servlet中,url-pattern取值为/表示拦截除了URL以JSP结尾以外的所有URL
@WebServlet("/")
public class MyServlet extends HttpServlet {
    private EmpController empController;
    @Override
    public void init(ServletConfig config) throws ServletException {
        WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());
        myController = wac.getBean("empController", EmpController.class);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = req.getRequestURI();
        // 因为在Tomcat插件配置的项目名叫做bjsxt,所以需要去掉uri中的/bjsxt/
        String path = uri.substring(7);
        System.out.println(path);
        if(path.equals("delete")){
            empController.delete();
        }else if(path.equals("showDept")){
            empController.showDept();
        }else if(path.equals("showEmp")){
            empController.showEmp();
        }
    }
}
1.3 使用Front设计模式优点

这样带来的好处是:

  • 只需要在一个Servlet中编写获取容器Bean的代码,减少了代码冗余

  • 不需要为每个控制器都创建一个类,而是可以在一个普通Java类中提供普通实例方法代表以前servlet中的service方法。

  • 因为可以自己编写普通Java类,这类可以放入到Spring容器中,注入Service更方便

  • 同时因为是自己编写的Java,所以可以进行一些封装,对其他操作进行简化

2. Spring MVC介绍

  • 本质为Spring 框架的一个扩展,在Spring官方ZIP包就是一个spring-webmvc.jar的jar包。
  • Spring MVC属于Spring Framework的二级子项目
  • Spring MVC是基于Front设计模式。
  • Spring MVC中已经帮助编写了前端入口的DispatcherServlet,里面编写了请求分发功能,但是并没有提供@WebServlet注解,需要我们在web.xml手动编写配置。
  • EmpController在Spring MVC称为控制器类(Handler),里面的方法称为:控制单元(HandlerMethod)

五:Day09_SpringMVC01_第2张图片

Spring MVC在MVC三层中都有自己的功能。例如:

M:在模型层包含:数据校验。

V:在视图层包含:国际化、标签库。

C:在控制层包含的功能就更多了:转发重定向、参数、拦截器、作用域等。

3. Spring中的父子容器问题(重要)

  • 因为Spring MVC属于Spring的子框架,所以Spring MVC中可以使用Spring框架的全部内容。
  • Spring MVC有一个专门的容器,这个容器里面放Spring MVC中全部Bean,且这个容器属于Spring容器的子容器。
  • Spring MVC子容器可以调用Spring 父容器的全部内容。但是Spring父容器不能调用Spring MVC子容器内容。

五:Day09_SpringMVC01_第3张图片

二、Spring MVC环境搭建(重要)

1. 创建项目并添加依赖

在只使用Spring MVC框架时需要导入spring-webmvc依赖即可。


        
            org.springframework
            spring-webmvc
            5.3.16
        

2. 创建Spring MVC配置文件

在resources中新建springmvc.xml。这个文件的名称是随意的,只要和web.xml中配置对应上就可以。

  
    
    
    

3. 编写web.xml内容(重要)

web.xml的配置是为了让前端控制器DispatcherServlet生效。并且加载Spring MVC的配置文件。

 Tomcat:
            1、由于配置了 1Tomcat启动时就会创建                       DispatcherServlet 对象。

            2、DispatcherServlet对象创建后会执行初始化方法, servletConfig对象读取                            servlet的初始化参数( ,根据读取到的初始化参数值创建                              springmvc容器。(设置spring容器为父容器,逻辑上的父子 关系)。                                  springmvc配置文件中配置了

                 

                 com.zqwl.controller 包中的类中存在@Controller注解,将该类交给springmvc                   容器管理。
            3、只要获取到了springmvc容器就可以获取springmvc容器中的控制类对象
            4、DispatcherServlet映射路径为 /,除了.jsp其他全部能够匹配。
客户端发起求:                      协议://ip:port/qqq,访问的资源 /qqq  和  DispatcherServlet 的映射路径 / 可以                     匹配。
            5、匹配后执行DispatcherServlet中  service  方法,从springmvc容器中获取控制                    类,通过控制器类找到控制单元,
                 可以根据 请求资源 和 控制单元 的注解值找到对应的控制单元,执行控制单元,                     处理请求。



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

4. 创建控制器类

@Controller// 放入到Spring MVC容器中
public class FirstController {
    /*
     * 官方标准写法:
     *      返回值是ModelAndView,对象中存储跳转资源路径及作用域值
     */
    // 当前方法的映射路径
    @RequestMapping("/first")
    public ModelAndView test1(){
        ModelAndView modelAndView = new ModelAndView("first.jsp");
        return modelAndView;
    }
    /*
     * 简化写法(平时使用的方式)
     *      返回值是String,表示跳转的资源路径
     */
    @RequestMapping("/first2")
    public String test2(){
        return "first.jsp";
    }
}

5. 新建first.jsp

在webapp下新建first.jsp。在文件中随意写一句话。

6. 测试访问结果

三、@RequestMapping注解(重点)

1.介绍

  • @RequestMapping注解可以写在控制器类上,也可以写在控制单元方法上。
  • 如果写在类上,表示当前类所有控制单元的映射路径,都以指定路径开头。
  • 如果写在方法上,表示当前方法的映射路径。最终访问这个控制单元的映射路径为:类上@RequestMapping映射路径+方法上@RequestMapping映射路径。
@Controller
@RequestMapping("/global")
public class FirstController {
    @RequestMapping("/first3")
    public String test3(){
        return "first.jsp";
    }
}

2.@RequestMapping注解的属性

在@RequestMapping注解中提供了很多参数。

五:Day09_SpringMVC01_第4张图片

  1.path:映射的路径。
           映射一个访问路径:path = {"aa"}  省略{}   path = "aa"
           映射多个访问路径:path = {"aa,bb"}。
  2.value:和path作用相同,只有一个value属性时,value可以省略。
  3.name:添加描述信息。
  4.method:允许的请求方式。
               RequestMethod.POST
               RequestMethod.GET
              ...
            简化:
               @GetMapping  为  @RequestMapping(method = RequestMethod.GET)
               @PostMapping  为  @RequestMapping(method = RequestMethod.POST)
               ...
   5.params:  指定请求中必须携带的请求参数。
   6.headers: 指定请求中必须携带的请求头。

   7.consumes:表示处理请求内容(Content-Type)的类型。
   8.produces:配合@ResponseBody注解使用,指定响应内容的类型。单独使用没有意                                义。

/*
* EmpController:为控制器类,控制器类中可以有多个控制单元。
* 本质为普通的bean,交给springmvc容器管理
* */
@RequestMapping("/lyx")
@Controller
public class EmpController {
    /* 控制单元 */
//请求映射(控制单元映射的路径)
  @RequestMapping(value = "/a" ,name="name属性")
    public String  querry(){
        System.out.println("querry执行了");
        return "/first.jsp";
    }
    @RequestMapping(value = "b",name = "value属性,只有value属性时,可以直接写value的值")
    public String bb(){
        System.out.println("value属性执行了");
        return "/first.jsp";
    }
    @RequestMapping(path = "c",name = "path属性和value属性使用方式是相同的,但是不可以省略")
    public String cc(){
        System.out.println("path属性执行了");
        return "/first.jsp";
    }
    /*
    * method属性类型是RequestMethod[],RequestMethod是枚举类型,支持HTTP协议中绝大多数请求类型。
    * */
    @RequestMapping(path = "d", method = RequestMethod.GET,name = " RequestMethod.GET 表示只接受GET情求")
    public String method1(){
        System.out.println("RequestMethod.GET属性执行了");
        return "/first.jsp";
    }
    @RequestMapping(path = "e", method = RequestMethod.POST,name = " RequestMethod.POST 表示只接受POST情求")
    //如果接收到GET请求,会在控制台提示 Request method 'GET' not supported
    public String method2(){
        System.out.println("RequestMethod.POST");
        return "/first.jsp";
    }
    @RequestMapping(path = "f", method = {RequestMethod.POST,RequestMethod.GET},
            name = " {RequestMethod.POST,RequestMethod.GET} 表示即接受POST情求又接收get请求")
    public String method3(){
        System.out.println("{RequestMethod.POST,RequestMethod.GET}");
        return "/first.jsp";
    }
    //简写方式
    @GetMapping("g")
    public String method4(){
        System.out.println("@GetMapping");
        return "/first.jsp";
    }
    @PostMapping("h")
    public String method5(){
        System.out.println("@PostMapping");
        return "/first.jsp";
    }
    //  params属性类型是String[],表示请求中必须包含指定名称的请求参数。
    @RequestMapping (value = "i",params = {"name","pwd"})//多个参数用{}
    public String params(){
        System.out.println("params");
        return "/first.jsp";
    }
    //headers属性类型是String[],表示请求头中必须包含指定的请求头参数。
    //consumers表示处理请求内容(Content-Type)的类型,平时多不设置,由Spring MVC自动判断。
   // produces类型是String[],作用是设置@ResponseBody注解的响应内容类型
    @RequestMapping (value = "aa",produces = "text/html;charset=utf-8",name = "设置@ResponseBody注解的响应内容类型")
    @ResponseBody
    public String produces() {
        System.out.println("produces");
        return "登龙";
    }
}

四、映射路径(重要)

1. 映射路径介绍

  • 映射路径就是web.xml中的值或者@WebServlet("")注解的值。
  • 映射路径无论是在Servlet中还是在Spring MVC中,都表示:当URL中出现指定路径时会执行Servlet的方法或执行Spring MVC的控制单元。

2. 多级路径

映射路径:写法上也支持路径的写法。在Java中路径是使用 / 进行分隔,表示目录层次。

在Spring MVC 的映射路径也支持多层写法,例如下面的代码表示URL为 http://localhost:8081/bjsxt/test/test2 时执行这个控制单元。

@RequestMapping("/test/test2")
public String test2(){
    return "first.jsp";
}

3. 多级路径中注意事项

映射路径中映射表示当控制器需要和视图资源进行跳转、引用等涉及到路径问题时会认为在webapp目录中映射一个虚拟资源。映射路径最后一个表示资源名称(test2),前面无论多少层都表示文件夹。

五:Day09_SpringMVC01_第5张图片

 所以在控制单元(/test/test2)跳转到视图资源(first.jsp)时,由于路径中写的是相对路径(return "first.jsp";)所以Tomcat会在webapp/test目录下找一个叫做first.jsp的文件。显然是不存在这样的资源,first.jsp是在webapp目录下。

3.1 多层路径中最优写法

只需要在返回值中使用绝对路径就可以减少出错的情况。跳转时 / 表示项目根目录,也就是webapp目录的根目录。

@RequestMapping("/test/test2")
public String test2(){
    return "/first.jsp";
}

4. Ant风格的映射路径

在Spring MVC中支持Ant风格的映射路径写法。所谓的Ant风格就是支持三种特殊的符号。

符号 解释
? 匹配任意单字符
* 匹配0或者任意数量的字符
** 匹配0或者更多数量的目录

解释说明:

使用Ant的特殊符号时,表示模糊匹配。可能出现客户端发送过来的URL能匹配上多个映射路径,这时的优先级为:

固定值 (bjsxt1) > ?形式(bjsxt?) > 一个*号(/*) > (/**)形式。

// 优先级最高
@RequestMapping("/bjsxt1")
public String testAnt1(){
    System.out.println("bjsxt");
    return "/first.jsp";
}
// 优先级低于bjsxt1。总长度为6,bjsxt开头,后面跟个任意内容符号
@RequestMapping("/bjsxt?")
public String testAnt2(){
    System.out.println("bjsxt");
    return "/first.jsp";
}
// 优先级低于?。一层路径,任意内容
@RequestMapping("/*")
public String testAnt3(){
    System.out.println("11111");
    return "/first.jsp";
}
// 优先级低于*。任意层路径
@RequestMapping("/**")
public String testAnt4(){
    System.out.println("22222");
    return "/first.jsp";
}

五、Spring MVC 中的转发和重定向(重要)

1. 转发和重定向复习

转发和重定向。这两个概念都是出现在资源之间相互跳转的。

两者区别:

(1)转发为一次请求,tomcat内部跳转。重定向为多次请求,不是tomcat内部跳转

(2)转发是一次请求,无论服务器内部转发多少次,请求对象都不变。所以转发可以共享            请求域的值。同时对于客户端浏览器URL是不变的。

        重定向后需要客户端重新发起请求,和重定向之前不是一个请求。所以重定向后不能获          取到之前设置在请求域的值。同时客户端浏览器URL是改变的。

(3)转发只能跳转到当前项目内部资源。重定向可以跳转到外部资源。例如:从自己的项目中跳转到百度应该使用重定向。

(4)转发时资源路径如果是绝对路径,第一个 / 表示当前项目根目录。

重定向时资源路径时绝对路径,第一个 / 表示 Tomcat 的 webapps目录,即:当前项目的上层目录。

转发的代码实现:

request.getRequestDispatcher("/first.jsp").forward(request,response);

重定向的代码实现:

response.sendRedirect("/bjsxt/first.jsp");

2. Spring MVC中的转发和重定向

  • 在Spring MVC框架中,默认情况下都使用转发进行寻找资源。
  • 在资源路径前面添加forward: 表示转发。因为写不写forward:都是转发,所以为了代码写起来简单一些,多省略forward: 
  • 如果希望使用重定向跳转到其他资源,只能在资源路径最前面明确添加redirect:,下面代码就是使用重定向方式的写法。
@RequestMapping("/test/test2")
public String test2(){
    return "redirect:/first.jsp";
}

3. Spring MVC转发和重定向时绝对路径

在Spring MVC中无论是转发还是重定向,使用绝对路径时/都表示项目根目录

这种设计对于开发者来说更加友好,不用在区分到底是转发,还是重定向了。

六、WEB-INF目录资源(重要)

1. WEB-INF目录资源介绍

  • 在平时学习过程中,我们多会把JSP文件放入到webapp目录中,或在webapp下新建一个目录把页面资源放入到目录中,这种情况JSP都是可以通过浏览器直接访问的。
  • 但是在一些特定的项目中,从安全性等方面考虑不希望客户端通过浏览器直接访问对应的资源。
  • 这时就可以把资源放入到WEB-INF目录中。因为在Java Web项目中规定:WEB-INF中资源是不允许被客户端直接访问,需要先访问控制器,通过控制器的转发来访问这些资源。
  • 这种目录结构也更加负责MVC开发模式,更能体现出控制器的作用。

2. 结果分析

如果项目中所有的JSP、CSS、JavaScript、图片都放入到WEB-INF中,那所有的资源都必须先执行控制器。这样对于刚学习这种写法的人可能觉得实现起来更加复杂了。但是从项目角度上却是更加安全了,也可以在控制器方法中加入自己想要加入的逻辑。

七、视图解析器(重点)

1. 视图解析器和视图

1.ModelAndView:模型数据(存储业务数据)和视图
               Model:模型数据(存储模型层中查询到的数据)
               View: 视图(页面属于视图中的一种)
 2. 控制单元执行完成后,将控制单元返回的结果固定封装为ModelAndView对象

    Model中存储了业务数据,View通常存储视图名。最终目的:将Model中的业务数据通过        视图 渲染客户端
           底层源码:
               ModelAndView mv;
               mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
              执行控制单元,控制单元返回结果封装为ModelAndView。

 3. 视图解析器:ViewResolver(接口),根据ModelAndView对象中解析出的视图名找到         对应的视图对象并返回。
   

示例: 

以.jsp视图为例:

    1.控制单元执行后,执行handle(processedRequest, response,                                                   mappedHandler.getHandler()),返回ModelAndView对象 (viewname为index.jsp)

    2.获取到ModelAndView后,执行render(mv, request, response); 

    3.在render方法中调用了view = resolveViewName(viewName, mv.getModelInternal(),               locale, request),获取到视图名

    4.resolveViewName方法中, 视图解析器 根据视图名找到对应的视图对象并返回。

         (1)默认的使用的视图解析器:InternalResourceViewResourceView。

         (2) .jsp的视图对象为:InternalResourceView

    5.返回视图对象后,调用view.render(mv.getModelInternal(), request, response)。实际完         成Model中的数据通过视图响应回到客户端。

    6. .jsp的InternalResourceView的视图对象渲染时:

          (1)将Model中的数据存储到请求域对象中。

          (2)将请求转发到.jsp -> .java(获取请求去对象中的数据)-> .class -> 将结果输出                        到客户端。

Spring MVC 定义了ViewResolverView接口:

  • 视图解析器用来解析逻辑视图,将其解析成真正的视图对象。
  • SpringMVC 提供了一个视图解析器的接口 ViewResolver,所有具体的视图解析器必须实现该接口。
  • AbstractCachingViewResolver:抽象类,这种视图解析器会把它曾经解析过的视图保存起来,然后每次要解析视图的时候先从缓存里面找,如果找到了对应的视图就直接返回,如果没有就创建一个新的视图对象,然后把它放到一个用于缓存的map中,接着再把新建的视图返回。使用这种视图缓存的方式可以把解析视图的性能问题降到最低。
  • UrlBasedViewResolver:它是对ViewResolver的一种简单实现,而且继承了AbstractCachingViewResolver,主要就是提供的一种拼接URL的方式来解析视图,它可以让我们通过prefix属性指定一个指定的前缀,通过suffix属性指定一个指定的后缀,然后把返回的逻辑视图名称加上指定的前缀和后缀就是指定的视图URL了。如prefix=/WEB-INF/,suffix=.jsp,返回的视图名称viewName=test,则UrlBasedViewResolver解析出来的视图URL就是/WEB-INF/test.jsp。默认的prefix和suffix都是空串。
  • InternalResourceViewResolver:它是URLBasedViewResolver的子类,所以URLBasedViewResolver支持的特性它都支持。在实际应用中InternalResourceViewResolver也是使用的最广泛的一个视图解析器。InternalResourceViewResolver解释为内部资源视图解析器。InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象,InternalResourceView会把Controller处理器方法返回的模型数据都存放到对应的request属性中,然后通过RequestDispatcher在服务器端把请求forword到目标URL
  • ThymeleafViewResolver:Thymeleaf视图解析器,映射成一个 Thymeleaf 模板文件。
  • FreeMarkerViewResolver:UrlBasedViewResolver的子类。FreeMarkerViewResolver会把Controller处理方法返回的逻辑视图解析为FreeMarkerView。

 

2. 自定义视图解析器

 对于项目结构比较固定,页面按照一定规则放在特定位置,且返回值内容比较长时,就可以配置视图解析器。在springmvc.xml配置下面内容。



    
    
    
    

配置了视图解析器后,控制单元返回值就不需要写前缀和后缀的内容了,写起来更加简单。

@RequestMapping("/showSuiyi")
public String showSuiyi(){
    return "suiyi";// 由视图解析器拼接:prefix + suiyi + suffix。具体:/WEB-INF/page/ + suiyi + .jsp
}

@RequestMapping("/showSuiyi2")
public String showSuiyi2(){
    return "suiyi2";// 由视图解析器拼接:prefix + suiyi + suffix。具体:/WEB-INF/page/ + suiyi2 + .jsp
}

3. 自定义视图解析器下跳转到其他控制器

当自定义视图解析器后,返回值前面和后面都会固定拼接字符串(在没有使用其他注解情况下)。但是如果控制单元执行完,并不希望跳转到视图,而是跳转到控制器,这时需要在返回值前面明确添加forward:或redirect: ,这样就不走视图解析器了。

@RequestMapping("/showSuiyi3")
public String showSuiyi3(){
    return "suiyi3";// 跳转到 /WEB-INF/page/suiyi3.jsp
}
@RequestMapping("/demo")
public String demo(){
    return "forward:/showSuiyi3"; // 不走视图解析器了。跳转到/showSuiyi3控制器单元
}

八、静态资源放行

1. 静态资源放行(重要)

按照SpringMVC的使用流程,需要在web.xml文件中配置DispatcherServlet的拦截范围,而我们配置的拦截范围为”/”,表示拦截除jsp请求以外的所有请求。这样造成,请求是js,css,图片等静态资源的请求,也会被拦截,调用对应的单元方法来处理请求。但是,我们是一个静态资源的请求,不应该按照普通单元方法请求的流程来处理,而是将对应的静态资源响应给浏览器使用。

Spring MVC 支持静态资源配置,当URL满足指定路径要求时不再去找控制单元,而是直接转发到特定路径中静态资源。

例如项目结构:  

五:Day09_SpringMVC01_第6张图片

需要在springmvc.xml中配置静态资源放行  :


	
	
	


九、控制单元的方法参数(接收请求参数)

1. 控制单元方法参数写法

(1) 紧耦方式。获取原生Servlet API,通过原生Servlet API获取请求参数、设置响应内容、设置作用域的值。

 (2)解耦方式。使用Spring MVC提供的方式获取请求参数、设置响应内容、设置作用域的值。

2. 紧耦方式

@RequestMapping("/demo")
public String demoServlet(HttpServletRequest req){
    String name = req.getParameter("name");
    return "index";
}
@RequestMapping("/out")
public void testOut(HttpServletResponse resp) throws IOException {
    resp.setContentType("text/html;charset=utf-8");
    PrintWriter out = resp.getWriter();
    out.print("bjsxt");
}

3. 解耦方式

解耦方式是Spring MVC独有方式。是Spring MVC给开发者提供的:

(1)获取请求中内容

(2)设置作用域值

(3)设置响应内容

等写法。

3.1 获取请求中内容(重要)
3.1.1 获取普通表单参数

获取普通表单参数,只需要包含在控制单元中提供与请求参数同名的方法参数即可。

Spring MVC会自动进行类型转换。

@RequestMapping("/testParam")
public String testParam(String name,Integer age){//用int类型在接收到null时会报错
    System.out.println(name+","+age);
    return "suiyi";
}

3.1.2 @RequestParam 注解(重要)

@RequestParam是方法参数级注解。每个控制单元方法参数前面都能写这个注解。在@RequestParam注解里面提供了四个属性,分别:

五:Day09_SpringMVC01_第7张图片

(1)name: 可以使用name指定请求参数名。

@RequestMapping("/testParam")
public String testParam(@RequestParam(name="name") String name123, Integer age){
    System.out.println(name123+","+age);
    return "suiyi";
}

 (2)value:是name属性的别名。功能和name属性相同。

 (3)defaultValue:默认值。表示当请求参数中没有这个参数时给与的默认值。

@RequestMapping("/testParam")
public String testParam(@RequestParam("name") String name123,@RequestParam(defaultValue = "16") Integer age){
    System.out.println(name123+","+age);
    return "suiyi";
}

(4)required:boolean类型,表示请求中是否必须包含此参数。

3.1.3 使用JavaBean作为参数(使用类对象作为控制单元参数)

当使用类对象作为参数时,要求属性名和参数名对应,类型转换由Spring MVC自动完成。不支持@RequestParam注解。

@RequestMapping("/testBean")
public String testBean(People peo){
    System.out.println(peo);
    return "suiyi";
}
3.1.4 JavaBean和简单数据类型混合使用

既然Spring MVC中又支持JavaBean的形式,又支持使用简单类型接收。当两种方式都使用时,且类中和简单类型重名时,Spring MVC会都给设置上。

3.1.5 接收多个同名表单参数(复选框的值)

 当使用数组进行接收时,需要数组对象名和请求参数名一致。如果不想一致,可以使用@RequestParam("hovers")定义请求参数名。

@RequestMapping("/testHover")
public String testHovers(String [] hovers){
    System.out.println(Arrays.toString(hovers));
    return "suiyi";
}
3.1.5.2 使用List接收多个同名请求参数

在使用List进行接收时,必须在参数前面添加@RequestParam注解,注解中内容就是请求参数名。

@RequestMapping("/testHover")
public String testHovers(@RequestParam("hovers") List hovers){
    System.out.println(hovers);
    return "suiyi";
}
3.1.6 接收日期类型参数

默认情况下必须保证客户端参数格式和服务器日期格式一致。可以在计算机屏幕右下角查看到日期格式。

所以只要保证客户端传递过来的日期是yyyy/MM/dd hh:mm:ss的格式,Spring MVC会自动进行类型转换。其中小时分钟秒可以省略不写。

@RequestMapping("/testDate")
public String testDate(Date date){
    System.out.println(date.toLocaleString());
    return "suiyi";
}
 3.1.6.1 @DateTimeFormat(重要)

如果觉得默认的格式无法满足要求,可以使用@DateTimeFormat自定义时间格式。

//@DateTimeFormat可以写在控制单元Date类型参数之前,也可以写在JavaBean的属性上面。
@RequestMapping("/testDate")
public String testDate(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
    System.out.println(date.toLocaleString());
    return "suiyi";
}
3.1.7 接收请求头数据

在HTTP协议中,请求头参数会有很多。如果希望接收请求头数据可以使用@RequestHeader进行接收。

在控制单元方法参数中添加对应名称的参数,并在参数前面添加@RequestHeader注解。

@RequestMapping("/testHeader")
public String testHeader(@RequestHeader String Accept){
    System.out.println(Accept);
    return "suiyi";
}
//Spring MVC对于接收请求参数时名称不区分大小写。所以下面的写法也是可以的。
@RequestMapping("/testHeader")
public String testHeader(@RequestHeader String accept){
    System.out.println(accept);
    return "suiyi";
}
3.1.8 获取请求体中内容

3.2 设置作用域的值
3.2.1 使用Model设置请求域的值

只需要在控制单元方法参数中添加Model对象,对象名称任意。

Model是一个接口,里面有很多子接口和实现类。当放置Model接口时,Spring MVC默认注入的是BindingAwareModelMap。

五:Day09_SpringMVC01_第8张图片

//在Model接口中有很多个方法,里面最常用的有两个addAttribute(String,Object)和addAllAtributes(Map)。
@RequestMapping("/testScope1")
public String testScope1(Model model){
    // 设置一个作用域值
    model.addAttribute("name","value");
    // 设置多个作用域值
    Map map = new HashMap<>();
    map.put("name2","value2");
    model.addAllAttributes(map);
    return "suiyi";
}
3.2.2 使用Map设置请求域的值

直接在控制单元方法上添加一个Map,然后向Map对象中put值就可以了。

@RequestMapping("/testScope2")
public String testScope2(Map map){
    map.put("name","value");
    return "suiyi";
}

十、Spring MVC 中文乱码问题

1. GET方式中文乱码解决

  • Tomcat8及之后的版本已经将Get请求乱码进行了处理,不需要额外处理。
  • Tomcat7默认的接收请求GET方式的是IOS-8859-1,如果希望正确的显示中文,还需要手动把内容转换为UTF-8编码。

方式一:  

@RequestMapping("/testEncoding")
public String testEncoding(String name) throws UnsupportedEncodingException {
    System.out.println("接收到name:"+name);
    String newName = new String(name.getBytes("iso-8859-1"),"utf-8");
    System.out.println("转换后的name:"+newName);
    return "suiyi";
}

 方式二:在tomcat中配置URIEncoding=utf-8。

2. POST方式中文乱码解决(重要)

  • 在Spring MVC提供了一个类CharacterEncodingFilter,里面直接写好了POST方式中文乱码解决代码。
  • 想让CharacterEncodingFilter生效,就需要在web.xml文件中配置下面内容。
  • 表示所有的请求编码都设置为UTF-8编码。


    code
  org.springframework.web.filter.CharacterEncodingFilter
    
        encoding
        utf-8
    


    code
    /*

你可能感兴趣的:(状态模式,1024程序员节)