SpringMVC框架----->(2) SpringMVC使用注解开发方式

SpringMVC注解开发

1、@RequestMapping定义请求规则

(1)指定模块名称(value属性)

  • 一个@Controller 所注解的类中,可以定义多个处理器方法。当然,不同的处理器方法所匹配的 URI 是不同的。这些不同的 URI 被指定在注解于方法之上的@RequestMapping 的 value 属性中。
  • @RequestMapping 该注解可以注解在方法上,也可以注解在类上,但意义是不同的。总的来说,要访问处理器的指定方法,必须要在方法指定 URI 之前加上处理器类前定义的模块名称

@RequestMapping:该注解在类的上面使用时
value:所有请求地址的公共部分,叫做模块名称
@RequestMapping:该类的处理器方法上面使用时
value:请求映射

例如:

  • 这里可以通过地址http://localhost:8080/springmvc/test/addUser.do可以访问处理器中的addUser方法
  • 同理通过地址http://localhost:8080/springmvc/test/removeUser.do可以访问处理器中的removeUser方法
@Controller
@RequestMapping(value = "/test")
public class MyController {
    
    

    @RequestMapping(value = "/addUser.do")
    public ModelAndView addUser(){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","张三");
        mv.addObject("lisi","李四");
        //当配置了视图解析器
        mv.setViewName("show");
        //返回视图
        return mv;
    }

    @RequestMapping(value = "/remove.do")
    public ModelAndView removeUser(){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","删除张三");
        mv.addObject("lisi","删除李四");
        mv.setViewName("show");
        return mv;
    }
}

(2)对请求提交方式的定义(method属性)

  • 对于@RequestMapping,其有一个属性 method,用于对被注解方法所处理请求的提交
    方式进行限制,即只有满足该 method 属性指定的提交方式的请求,才会执行该被注解方法。
  • Method 属性的取值为 RequestMethod 枚举常量。常用的为 RequestMethod.GET 与
    RequestMethod.POST,分别表示提交方式的匹配规则为 GET 与 POST 提交
  • 客户端浏览器常用的请求方式,及其提交方式有以下几种:
  • 也就是说,只要指定了处理器方法匹配的请求提交方式为 POST,则相当于指定了请求发送的方式:要么使用表单请求,要么使用 AJAX 请求。其它请求方式被禁用。
  • 当然,若不指定 method 属性,则无论是 GET 还是 POST 提交方式,均可匹配。即对于请求的提交方式无要求。

例如:
修改处理器类如下:

@Controller
@RequestMapping(value = "/test")
public class MyController {
    
    

    //指定addUser.html使用get请求方式
    @RequestMapping(value = "/addUser.do",method = RequestMethod.GET)
    public ModelAndView addUser(){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","张三");
        mv.addObject("lisi","李四");
        //当配置了视图解析器
        mv.setViewName("show");
        //返回视图
        return mv;
    }

    //指定remove.html使用post请求方式
    @RequestMapping(value = "/remove.do",method = RequestMethod.POST)
    public ModelAndView removeUser(){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","删除张三");
        mv.addObject("lisi","删除李四");
        mv.setViewName("show");
        return mv;
    }

    //指定update.html没有限制请求方式
    @RequestMapping(value = "/update.do")
    public ModelAndView updateUser(){
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","更新张三");
        mv.addObject("lisi","更新李四");
        mv.setViewName("show");
        return mv;
    }
}

修改index页面如下:

<body>
    <a href="test/addUser.do">添加用户(使用get请求方式)</a><br>

    <form action="test/remove.do" method="post">
        <input type="submit" value="删除用户(使用post请求方式)">
    </form>

    <a href="test/update.do">更新用户get(没有限制请求方式)</a><br>

    <form action="test/update.do" method="post">
        <input type="submit" value="更新用户post(使用post请求方式)">
    </form>
</body>

2、处理器方法的参数

  • 处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序员可在方法内直接使用。
  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • 用户提交的数据 1)逐个接收 2)对象接收

(1)逐个参数接收(参数名一样)

  • 只要保证请求参数名与该请求处理方法的参数名相同即可

例如:

A、修改index页面
<p>提交参数给Controller</p>
<form action="test/submit.do" method="post">
    姓名:<input type="text" name="name"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交参数">
</form>
B、修改处理器类方法
@RequestMapping(value = "/submit.do",method = RequestMethod.POST)
public ModelAndView addUser(String name,Integer age){
    
    
    System.out.println("name="+name+"age="+age);//name=zs age=null
    //可以在方法中直接使用name,age
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname",name);
    mv.addObject("myage",age);
    //当配置了视图解析器
    mv.setViewName("show");
    //返回视图
    return mv;
}

注意
在提交请求参数时,使用POST方式提交请求中文有乱码,需要使用过滤器处理乱码问题

解决方案:
  • 在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。
<!--声明过滤器,解决post乱码问题-->
<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>
    <!--强制请求对象(HttpServletRequest)使用encoding编码的值-->
    <init-param>
        <param-name>forceRequestEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
    <!--强制请求对象(HttpServletResponse)使用encoding编码的值-->
    <init-param>
        <param-name>forceResponseEncoding</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <!--/*:表示强制所有的请求先通过过滤器处理-->
    <url-pattern>/*</url-pattern>
</filter-mapping>
源码分析:
  • 字符集设置核心方法:
    在这里插入图片描述

(2)逐个参数接收(参数名不一样)

  • 所谓校正请求参数名,是指若请求 URL 所携带的参数名称与处理方法中指定的参数名不相同时,则需在处理方法参数前,添加一个注解@RequestParam(“请求参数名”),指定请求 URL 所携带参数的名称。

@RequestParam:解决请求中参数名不一样的问题
属性
1、value 请求中的参数名称
2、required是一个boolean,默认是true,表示请求中必须包含此参数,false 表示可以没有此参数

例如:

A、修改index页面
<p>提交参数名和控制器中的形参名不一样</p>
<form action="test/requestParam.do" method="post">
    姓名:<input type="text" name="rname"><br>
    年龄:<input type="text" name="rage"><br>
    <input type="submit" value="提交参数">
</form>
B、修改处理器类方法
@RequestMapping(value = "/requestParam.do")
public ModelAndView requestParam(@RequestParam(value = "rname",required = false)String name,
                                 @RequestParam(value = "rage",required = false) Integer age){
    
    
    System.out.println("name="+name+"age="+age);//name=zs age=null
    //可以在方法中直接使用name,age
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname",name);
    mv.addObject("myage",age);
    //当配置了视图解析器
    mv.setViewName("show");
    //返回视图
    return mv;
}

(3)对象参数接收

  • 将处理器方法的参数定义为java对象,只要保证请求参数名与这个对象的属性同名即可。

例如:

A、定义Student类
public class Student {
    
    
    /**
     * 属性名和请求中参数名一致
     */
    private String name;
    private Integer age;
    //这里省略set、get方法
}
B、修改index页面
<p>使用Java对象接收请求参数</p>
<form action="test/receiveObject.do" method="post">
    姓名:<input type="text" name="name"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交参数">
</form>
C、修改处理器类方法
/**
 * 处理器方法形参是Java对象,这个对象的属性名和请求中参数名不一样
 * 请求中参数是name,框架会调用setName()方法给属性赋值
 *
 */
@RequestMapping(value = "/receiveObject.do")
public ModelAndView receiveObject(Student student){
    
    
    System.out.println("name="+student.getName()+",age="+student.getAge());
    //可以在方法中直接使用name,age
    ModelAndView mv = new ModelAndView();
    mv.addObject("myname",student.getName());
    mv.addObject("myage",student.getAge());
    mv.addObject("mystudent",student);
    //当配置了视图解析器
    mv.setViewName("show");
    //返回视图
    return mv;
}

3、处理器方法的返回值

  • 使用@Controller 注解的处理器的处理器方法,其返回值常用的有四种类型:
  • 第一种:ModelAndView
  • 第二种:String
  • 第三种:无返回值 void
  • 第四种:返回自定义类型对象

(1)返回ModelAndView

  • 若处理器方法处理完后,需要跳转到其它资源,且又要在跳转的资源间传递数据,此时处理器方法返回 ModelAndView 比较好。

(2)返回String

  • 处理器方法返回的字符串可以指定逻辑视图名,通过视图解析器解析可以将其转换为物理视图地址。
/**
 * 处理返回结果String:表示逻辑视图名称,需要配置视图解析器
 * @param name
 * @param age
 * @return
 */
@RequestMapping(value = "/returnString-view.html")
public String doReturnView(HttpServletRequest request,String name, Integer age){
    
    
    System.out.println("name="+name+",age="+age);
    request.setAttribute("myname",name);
    request.setAttribute("myage",age);
    //show:逻辑视图名称,项目中配置了视图解析器
    return "show";
}

/**
 * 不配置视图解析器的情况
 */
@RequestMapping(value = "/returnString-view2.html")
public String doReturnView2(HttpServletRequest request,String name, Integer age){
    
    
    System.out.println("name="+name+",age="+age);
    request.setAttribute("myname",name);
    request.setAttribute("myage",age);
    //完整视图路径,项目中不能配置视图解析器,否则会出现404错误
    return "/WEB-INF/jsp/show.jsp";
}

4、解读< url-pattern>

(1)*.do

在没有特殊要求的情况下,SpringMVC 的中央调度器 DispatcherServlet 的< url-pattern/ >
常使用后辍匹配方式,如写为*.do 或者 *. action, *. mvc 等。

(2)/

可以写为 /,因为 DispatcherServlet 会将向静态资源的获取请求,例如 . css、. js、. jpg、. png 等资源的获取请求,当作是一个普通的 Controller 请求。中央调度器会调用处理器映射器为其查找相应的处理器。当然也是找不到的,所以在这种情况下,所有的静态资源获取请求也均会报 404 错误

5、静态资源的访问

http://localhost:8080/ch05_url_pattern/index.jsp :tomcat(jsp会转为servlet)
http://localhost:8080/ch05_url_pattern/js/jquery-3.4.1.js : tomcat
http://localhost:8080/ch05_url_pattern/images/p1.jpg : tomcat
http://localhost:8080/ch05_url_pattern/html/test.html: tomcat
http://localhost:8080/ch05_url_pattern/some.do :  DispatcherServlet(springmvc框架处理的)

tomcat本身能处理静态资源的访问, 像html, 图片, js文件都是静态资源< url-pattern/ >的值并不是说写为 / 后,静态资源就无法访问了。经过一些配置后,该问题也是可以解决的。

(1)使用< mvc:default-servlet-handler/ >

  • 声 明 了 < mvc:default-servlet-handler /> 后 , springmvc 框 架 会 在 容 器 中 创 建DefaultServletHttpRequestHandler 处理器对象。它会像一个检查员,对进入 DispatcherServlet 的 URL 进行筛查,如果发现是静态资源的请求,就将该请求转由 Web 应用服务器默认的Servlet 处理。一般的服务器都有默认的 Servlet。
  • 在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet。在 Tomcat 中,有一个专门用于处理静态资源访问的 Servlet 名叫 DefaultServlet。
<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>  表示静态资源和未映射的请求都这个default处理
</servlet-mapping>
default这个servlet作用:

1、处理静态资源
2、处理未映射到其它servlet的请求

只需在springmvc配置文件中添加< mvc:default-servlet-handler/ >标签即可

<!-- 声明注解驱动-->
<mvc:annotation-driven />

<!--第一种处理静态资源的方式:
    需要在springmvc配置文件加入 <mvc:default-servlet-handler>
    原理是: 加入这个标签后,框架会创健控制器对象DefaultServletHttpRequestHandler(类似我们自己创建的MyController).
    DefaultServletHttpRequestHandler这个对象可以把接收的请求转发给 tomcat的default这个servlet。
-->
<mvc:default-servlet-handler />

注意
default-servlet-handler 和 @RequestMapping注解有冲突, 需要在springmvc中加入注解驱动 annotation-driven 解决问题

(2)使用< mvc:resources/ >

mvc:resources 加入后框架会创建 ResourceHttpRequestHandler这个处理器对象。让这个对象处理静态资源的访问,不依赖tomcat服务器。
mapping:访问静态资源的uri地址, 使用通配符 **
location:静态资源在你的项目中的目录位置

images / ** :表示
images/p1.jpg , images/user/logo.gif , images/order/history/list.png

配置形式:

<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/html/**" location="/html/" />
<mvc:resources mapping="/js/**" location="/js/" />

<!--mvc:resources和@RequestMapping有一定的冲突-->
<mvc:annotation-driven />

<!--使用一个配置语句,指定多种静态资源的访问-->
<mvc:resources mapping="/static/**" location="/static/" />

目录位置:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hcz666/article/details/113954682