SpringMVC(第三天)

注解的引入

回顾

上一期我们写到原生版本的SpringMVC的执行流程

  1. 配置web.xml的DispatcherSrevlet和Spring容器
  2. Spring容器的配置文件使用bean注册处理器映射器,处理器适配器,和视图解析器
  3. 写一个类实现Controller表示这个就是Controller,并返回ModelAndView给视图解析器

显而易见这样我们能清晰的分析出SpringMVC的执行流程

用户的请求交给服务器,服务器会在启动的时候加载web.xml文件注册了DispathcerServlet并指出Sping容器的加载文件,这时前端处理器会根据请求进行映射,处理器映射的这个类在Spring容器中已经注册过了,映射器(HandlerMapping)会把请求映射为HandlerExecutionChain类型的handler对象交给这个中央控制器;然后中央处理器将handler对象作为参数传递给适配器(HandlerAdapter)的实例化对象,适配器对其进行处理,还会调用其他模型层最后返回ModelAndView给前端处理器。前端处理器调用视图解析器对视图名进行前缀和后缀拼接,并且前端处理器进行视图渲染(将模型装入view中)。

具体的流程我们是清楚了,但是实际开发我们不会采取这样的方法,太过于复杂,下面来介绍介绍注解开发

@Controller注解

使用这个注解直接表示这个类是Controller,不需要再实现controller接口并重写方法。
为了保证Spring能找到控制器类,还需要在Sping容器配置文件中添加扫描配置信息。如下:

(1)配置文件中引入约束spring-context
(2)使用<context:component-scan base-package="com.sang.controller"/>这里的base-package表示的是包名,需要扫描的包名。

这里<context:component-scan base-package="com.sang.controller"/>指定了com.sang.controller这个包,在运行的时候,该包以及包下所有标注了注解的类都会被Spring所识别并处理。

  • 控制器负责解析用户的请求并且将其转化为一个模型
  • 其中规定了各样的复杂的访问应用程序的方式

对比
使用注解的方式比原生的方法更加简单,同时,原生实现的实现类只能处理一个单一的请求动作,而基于注解的方式可以同时处理多个请求动作,更加灵活,节省开发者的效率

@RequestMapping注解

Spring容器通过@Controller注解找到相应的 控制器类后,还需要知道控制器内部是对每个请求是如何处理的,这就需要使用RequestMqpping注解类型。RequestMapping注解类型用于映射一个请求或者一个方法。

  • 当标注在方法上时
    表示该请求会直接映射成指定的value值,例如:
    @RequestMapping(value= "/admin")
    public String fun1(Model model){
        model.addAttribute("msg","hello!");
        return "hello";
    }

当用户发送请求http://localhost:8080/springmvc-05/adminDispatcherServlet会直接找项目下/admin对应的方法,这个方法中,传递了参数Model类型的数据,加入了一个字符串属性的值,方法最后返回一个字符串,而字符串返回到视图解析器中,视图解析器会根据规定的前缀和后缀来拼接字符串就像/WEB-INF/jsp/hello.jsp,然后给前端控制器,随后前端控制将模型渲染在jsp或者其他的前端模板页面里,返回给用户。

  • 当标注在类上时
@Controller
@RequestMapping(value= "/user")
public class MyCotroller{
		@RequestMapping("/admin")
	    public String fun1(Model model){
	        model.addAttribute("msg","hello!");
	        return "hello";
	    }
}

当用户在地址栏上访问localhost:8080/springmvc-05/user/admin同上原理一致,但是访问的请求在层级目录上分的很明确,用户在/user下访问/admin请求,中央处理器就会处理指定的“层级目录”下的请求方法,然后返回给视图解析器一个视图名称,最后解析为“WEB-INF/jsp/xxx.jsp"让中央处理器去返回给用户。

@RequestMapping注解的属性

属性名类型描述
nameString可选属性,用于为映射地址指定别名
valueString[ ]可选属性,用于指定映射的地址,用于映射一个方法或者一个类
methodRequestMethod[ ]可选的属性,用于指定请求的方式有GET,POST,DELETE,HEDA,OPTIONS,PUT,PATCH,TRACE
paramsString[ ]可选的属性,用于指定Request所传递的参数,必须有这些参数才可以通过这个方法进行处理
headersString[ ]可选的属性,用于指定Request所传递的headers的值,必须有这些参数才可以通过这个方法进行处理
consumesString[ ]可选的属性,用于指定处理请求的提交内容类型(Context-type)
producesString[ ]可选的属性,用于指定返回的内容类型,返回的内容类型必须是请求头中所包含的类型

啥也不写,默认的属性是value

@RequestMapping的组合注解

目的:简化HTTP方法的映射

  • GetMapping:匹配Get方式的请求
  • PostMapping:匹配Post方式的请求
  • PutMapping:匹配Put方式的请求
  • DeleteMapping:匹配Delete方式的请求
  • PatchMapping:匹配Patch方式的请求
    标注了@GetMapping的方法的请求如下
    @GetMapping(value= "/admin")
    public String fun1(Model model){
        model.addAttribute("msg","hello!");
        return "hello";
    }

与@RequestMapping注解方法(如下)一致

    @RequestMapping(value= "/admin",method=RequestMethod)
    public String fun1(Model model){
        model.addAttribute("msg","hello!");
        return "hello";
    }

@RequestMapping返回值(结果跳转方式)

在我们常见的SpringMVC的使用中,我们见过最多的是return一个字符串
如下:

    @GetMapping(value= "/admin")
    public String fun1(Model model){
        model.addAttribute("msg","hello!");
        return "hello";
    }

这里String类型的返回值会被"Servlet"传递到视图解析器中,视图解析器得到字符串会拼接前缀和后缀,成为“/WEB-INF/jsp/hello.jsp”,然后ViewResolver就会把该逻辑视图路径解析为真正的View视图对象,然后通过View的渲染,将最终结果返回给中央处理器,然后呈现给用户

但是还有另外的使用方法:
ServletAPI

通过设置ServletAPI , 不需要视图解析器 .

1、通过HttpServletResponse进行输出

2、通过HttpServletResponse实现重定向

3、通过HttpServletResponse实现转发

@Controller
public class ResultGo {

   @RequestMapping("/result/t1")
   public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.getWriter().println("Hello,Spring BY servlet API");
  }

   @RequestMapping("/result/t2")
   public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
       rsp.sendRedirect("/index.jsp");
  }

   @RequestMapping("/result/t3")
   public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
       //转发
       req.setAttribute("msg","/result/t3");
       req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
  }

}

我们的Controller里的标注了注解的方法其实也就相当于一个个的Servlet,直接通过Servlet的API进行视图转发,这时不需要制图解析器,不信可以注释掉MVC配置文件中的视图解析器。

转发和重定向

测试前,需要将视图解析器注释掉

@Controller
public class ResultSpringMVC {
   @RequestMapping("/rsm/t1")
   public String test1(){
       //转发
       return "/index.jsp";
  }

   @RequestMapping("/rsm/t2")
   public String test2(){
       //转发二
       return "forward:/index.jsp";
  }

   @RequestMapping("/rsm/t3")
   public String test3(){
       //重定向
       return "redirect:/index.jsp";
  }
}

重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方嘛 , 所以注意路径问题.可以重定向到另外一个请求实现 .

@Controller
public class ResultSpringMVC2 {
   @RequestMapping("/rsm2/t1")
   public String test1(){
       //转发
       return "test";
  }

   @RequestMapping("/rsm2/t2")
   public String test2(){
       //重定向
       return "redirect:/index.jsp";
       //return "redirect:hello.do"; //hello.do为另一个请求/
  }

}

RestFul风格

  • 概念
    Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
  • 功能
    资源:互联网所有的事物都可以被抽象为资源
    资源操作:使用POST、DELETE、PUT、GET使用不同方法对资源进行操作。
    分别对应 添加、 删除、修改、查询。
  • 传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get

    http://localhost/item/queryItem.action?id=1 查询,GET

    http://localhost/item/saveItem.action 新增,POST

    http://localhost/item/updateItem.action 更新,PUT

    http://localhost/item/deleteItem.action?id=1 删除,GET或POST

  • RestFul风格
    使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!

    http://127.0.0.1/item/1 查询,GET

    http://127.0.0.1/item 新增,POST

    http://127.0.0.1/item 更新,PUT

    http://127.0.0.1/item/1 删除,DELETE

演示

Controller层

	@GetMapping(value="/admin/{a}/{b}")
    public String test(@PathVariable int a,@PathVariable int b, Model model){
        model.addAttribute("msg",a+b);
        return "hello";
    }

访问http://localhost:8080/springmvc-05/admin/1/5结果如下:
在这里插入图片描述
这里@PathVariable int a,@PathVariable int b会将URL里的参数赋值,最后在model中加入参数msg的值是a+b,呈现给用户。

  • RestFul风格的好处:URL更加简洁,获取参数更加方便,框架会自动进行类型转换。
  • 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/commit/1/a,则路径与方法不匹配,而不会是参数转换失败。
  • 所有的地址栏请求默认都会是 HTTP GET 类型的。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值