Spring MVC中@Controller和@RequestMapping注解使用

目录
  • @Controller和@RequestMapping注解使用
    • RequestMapping 注解类型
    • 通过 @RequestParam 接收请求参数
      • Spring MVC应用@Autowired和@Service进行依赖注入
      • 通过 org.springframework.web.bind.annotation.ModelAttribute
      • 拦截器的配置 
  • @RequestMapping和Controller方法返回值
    • @RequestMapping
      • Controller方法返回值

      @Controller和@RequestMapping注解使用

      RequestMapping 注解类型

      1)方法级别注解

      @RequestMapping(value = "/index/login")
      public String login() {
      /**
      * login代表逻辑视图名称,需要根据Spring MVC配置
      * 文件中internalResourceViewResolver的前缀和后缀找到对应的物理视图
      */
      return "login";
      }

      2)类级别注解

      @RequestMapping("/index")
      public class IndexController {
      }

      通过 @RequestParam 接收请求参数

      @RequestMapping("/register")
      /**
      * 通过@RequestParam接收请求参数
      */
      public String register(@RequestParam String uname,
          @RequestParam String upass, Model model) {
          if ("zhangsan".equals(uname) && "123456".equals(upass)) {
              logger.info("成功");
              return "login"; // 注册成功,跳转到 login.jsp
          } else {
              // 在register.jsp页面上可以使用EL表达式取出model的uname值
              model.addAttribute("uname", uname);
              return "register"; // 返回 register.jsp
          }
      }
      @RequestMapping("/register")
      public String register(@ModelAttribute("user") UserForm user) {
          if ("zhangsan".equals(uname) && "123456".equals(upass)) {
              logger.info("成功");
              return "login"; // 注册成功,跳转到 login.jsp
          } else {
              logger.info("失败");
              // 使用@ModelAttribute("user")与model.addAttribute("user",user)的功能相同
              //register.jsp页面上可以使用EL表达式${user.uname}取出ModelAttribute的uname值
              return "register"; // 返回 register.jsp
          }
      }

      Spring MVC应用@Autowired和@Service进行依赖注入

      <context:component-scan base-package="service" />

      通过 org.springframework.web.bind.annotation.ModelAttribute

      注解类型可经常实现以下两个功能:

      1.绑定请求参数到实体对象(表单的命令对象)

      @RequestMapping("/register")
      public String register(@ModelAttribute("user") UserForm user) {
          if ("zhangsan".equals(uname) && "123456".equals(upass)) {
              logger.info("成功");
              return "login";
          } else {
              logger.info("失败");
              return "register";
      }

      在上述代码中“@ModelAttribute("user")UserForm user”语句的功能有两个:

      将请求参数的输入封装到 user 对象中。

      创建 UserForm 实例。

      以“user”为键值存储在 Model 对象中,和“model.addAttribute("user",user)”语句的功能一样。如果没有指定键值,即“@ModelAttribute UserForm user”,那么在创建 UserForm 实例时以“userForm”为键值存储在 Model 对象中,和“model.addAtttribute("userForm", user)”语句的功能一样。

      2.注解一个非请求处理方法 

      被 @ModelAttribute 注解的方法将在每次调用该控制器类的请求处理方法前被调用。这种特性可以用来控制登录权限,当然控制登录权限的方法有很多,例如拦截器、过滤器等。

      拦截器的配置 

      让自定义的拦截器生效需要在 Spring MVC 的配置文件中进行配置,配置示例代码如下:

      <!-- 配置拦截器 -->
      <mvc:interceptors>
          <!-- 配置一个全局拦截器,拦截所有请求 -->
          <bean class="interceptor.TestInterceptor" /> 
          <mvc:interceptor>
              <!-- 配置拦截器作用的路径 -->
              <mvc:mapping path="/**" />
              <!-- 配置不需要拦截作用的路径 -->
              <mvc:exclude-mapping path="" />
              <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
              <bean class="interceptor.Interceptor1" />
          </mvc:interceptor>
          <mvc:interceptor>
              <!-- 配置拦截器作用的路径 -->
              <mvc:mapping path="/gotoTest" />
              <!-- 定义在<mvc: interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
              <bean class="interceptor.Interceptor2" />
          </mvc:interceptor>
      </mvc:interceptors> 

      在上述示例代码中,<mvc:interceptors> 元素用于配置一组拦截器,其子元素 <bean> 定义的是全局拦截器,即拦截所有的请求。

      <mvc:interceptor> 元素中定义的是指定路径的拦截器,其子元素 <mvc:mapping> 用于配置拦截器作用的路径,该路径在其属性 path 中定义。

      如上述示例代码中,path 的属性值“/**”表示拦截所有路径,“/gotoTest”表示拦截所有以“/gotoTest”结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 <mvc:exclude-mapping> 子元素进行配置。

      需要注意的是,<mvc:interceptor> 元素的子元素必须按照 <mvc:mapping.../>、<mvc:exclude-mapping.../>、<bean.../> 的顺序配置。

      @RequestMapping和Controller方法返回值

      @RequestMapping

      通过@RequestMapping注解可以定义不同的处理器映射规则。

      1. URL路径映射

      @RequestMapping(value="/item") 或 @RequestMapping("/item") --当括号里有多个属性时,value=不可以省略。

      value的值是数组,可以将多个url映射到同一个方法。

      /**
       * 查询商品列表
       * @return
       */
      @RequestMapping(value = { "itemList", "itemListAll" })
      public ModelAndView queryItemList() {
          // 查询商品数据
          List<Item> list = this.itemService.queryItemList(); 
          // 创建ModelAndView,设置逻辑视图名
          ModelAndView mv = new ModelAndView("itemList"); 
          // 把商品数据放到模型中
          mv.addObject("itemList", list);
          return mv;
      }

      2. 添加在类上面

      在class上添加@RequestMapping(url)指定通用请求前缀,限制此类下的所有方法请求url必须以请求前缀开头

      可以使用此方法对url进行分类管理,如下图:

      此时需要进入queryItemList()方法的请求url为:http://127.0.0.1:8080/api/item/itemList.action

      或者

      http://127.0.0.1:8080/api/item/itemListAll.action

      3.请求方法限定

      除了可以对url进行设置,还可以限定请求进来的方法。不写的话默认所有方法都可以。

      (1)限定GET方法

      @RequestMapping(method = RequestMethod.GET)

      如果通过POST访问则报错:

      HTTP Status 405 - Request method 'POST' not supported

      例如:

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

      (2)限定POST方法

      @RequestMapping(method = RequestMethod.POST)

      如果通过GET访问则报错:

      HTTP Status 405 - Request method 'GET' not supported

      (3)GET和POST都可以

      @RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})

      Controller方法返回值

      1. 返回ModelAndView --无敌的,带着数据,返回视图路径

      controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。

      @RequestMapping(value = "/item/itemlist.action")
      public ModelAndView itemList(){     
          // 从MySQL中查询数据
          List<Items> list = itemService.selectItemsList(); 
          // 创建ModelAndView,用来存放数据和视图
          ModelAndView mav = new ModelAndView();
          // 设置数据到模型中
          mav.addObject("itemList", list); //页面上循环的是itemList
          // 设置视图的路径,需要设置视图的物理地址
          //mav.setViewName("/WEB-INF/jsp/itemList.jsp");
          mav.setViewName("itemList"); //在springmvc.xml中替换掉默认的视图解析器 
          return mav;
      }

      2. 返回void --数据通过形参 Model model 或者 ModelMap model,但是没办法return视图。

      如果需要返回视图得通过request或response。这种比较适合ajax请求,但是给ajax返回数据得json格式数据。

      在Controller方法形参上可以定义request和response,使用request或response指定响应结果:

      (1)使用request转发页面,如下:

      request.getRequestDispatcher("页面路径").forward(request, response);
      request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request, response);

      (2)可以通过response页面重定向:

      response.sendRedirect("url")
      response.sendRedirect("/itemEdit.action");

      (3)可以通过response指定响应结果,例如响应json数据如下:

      response.getWriter().print("{\"abc\":123}");

      代码:

      /**
       * 返回void测试
       *
       * @param request
       * @param response
       * @throws Exception
       */
      @RequestMapping("queryItem")
      public void queryItem(HttpServletRequest request, HttpServletResponse response) throws Exception {
          // 1 使用request进行转发
          // request.getRequestDispatcher("/WEB-INF/jsp/success.jsp").forward(request,
          // response);
       
          // 2 使用response进行重定向到编辑页面
          // response.sendRedirect("/springmvc-web2/itemEdit.action");
       
          // 3 使用response直接显示
          response.getWriter().print("{\"abc\":123}");
      }

      【注意】:改映射@RequestMapping、改方法名、改方法形参、改返回值都需要重启程序,其他不需要重启。

      3.返回字符串(官方推荐此种方式) --返回视图路径,数据通过形参 Model model 或者 ModelMap model

      (1)逻辑视图名

      controller方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。

      //指定逻辑视图名,经过视图解析器解析为jsp物理路径:/WEB-INF/jsp/itemList.jsp
      return "itemList";

      示例代码:

      /**
       * 根据id查询商品,绑定简单数据类型
       *
       * @param id
       * @param model
       * @return
       */
      @RequestMapping("/itemEdit.action")
      public String queryItemById(Integer id, ModelMap model) { //不要用int,万一传进来一个long
          // 根据id查询商品数据
          Items item = this.itemService.selectItemsById(id);
       
          // 把商品数据放在模型中
          model.addAttribute("item", item);
       
          return "editItem";
      }

      (2)Redirect重定向

      Contrller方法返回字符串可以重定向到一个url地址。

      如下商品修改提交后重定向到商品编辑页面。

      /**
        * 更新商品
        *
        * @param item
        * @return
        */
       @RequestMapping("updateItem")
       public String updateItemById(Items item) {
           // 更新商品
           this.itemService.updateItemById(item);
       
           // 修改商品成功后,重定向到商品编辑页面
           // 重定向后浏览器地址栏变更为重定向的地址,
           // 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
           // 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
           return "redirect:/itemEdit.action?itemId=" + item.getId();
       }

      (3)forward转发

      Controller方法执行后继续执行另一个Controller方法

      如下商品修改提交后转向到商品修改页面,修改商品的id参数可以带到商品修改方法中。

      /**
       * 更新商品
       *
       * @param item
       * @return
       */
      @RequestMapping("updateItem")
      public String updateItemById2(Items item) {
          // 更新商品
          this.itemService.updateItemById(item);
       
          // 修改商品成功后,重定向到商品编辑页面
          // 重定向后浏览器地址栏变更为重定向的地址,
          // 重定向相当于执行了新的request和response,所以之前的请求参数都会丢失
          // 如果要指定请求参数,需要在重定向的url后面添加 ?itemId=1 这样的请求参数
          // return "redirect:/itemEdit.action?itemId=" + item.getId();
       
          // 修改商品成功后,继续执行另一个方法
          // 使用转发的方式实现。转发后浏览器地址栏还是原来的请求地址,
          // 转发并没有执行新的request和response,所以之前的请求参数都存在
          return "forward:/itemEdit.action"; 
      }

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持。 

      本文转自网络,如有侵权请联系客服删除。