学习内容:控制器和RestFul风格
一、控制器(Controller)
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
- 控制器负责解析用户的请求并将其转换为一个模型。
- 在Spring MVC中一个控制器类可以包含多个方法
- 在Spring MVC中,对于Controller的配置方式有很多种
1、实现Controller接口
Controller是一个接口,在org.springframework.web.servlet.mvc包下,接口中只有一个方法
//实现该接口的类获得控制器功能
public interface Controller {
//处理请求且返回一个模型与视图对象
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
1、和第一个SpringMVC程序一样,
首先新建一个maven项目,并添加web支持
导入依赖
配置web.xml , 注册DispatcherServlet
编写SpringMVC 的 配置文件
2、然后编写一个控制类ControllerTest.java
ControllerTest.java
//只要实现了Controller接口的类,说明这就是一个控制器
public class ControllerTest implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest01");
mv.setViewName("test");
return mv;
}
}
3、编写完毕后,去Spring配置文件中注册请求的bean;name对应请求路径,class对应处理请求的类
<bean id="/test1" class="controller.ControllerTest"/>
4、编写前端test.jsp,注意在WEB-INF/jsp目录下编写,对应我们的视图解析器
test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
5、配置tomcat,运行
说明:
- 实现接口Controller定义控制器是较老的办法
- 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;
2、使用注解@Controller
@Controller
-
@Controller
注解类型用于声明Spring类的实例是一个控制器 - Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描。
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="controller"/>
@RequestMapping
@RequestMapping
注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。- 为了测试结论更加准确,我们可以加上一个项目名测试(http://localhost:8080 / 项目名 / xxx)
和上面一样
新建一个maven项目,并添加web支持
导入依赖
配置web.xml , 注册DispatcherServlet
1、编写SpringMVC 的 配置文件
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: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.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
<context:component-scan base-package="controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
2、创建一个ControllerTest02类,使用注解实现
ControllerTest02 .java
/*
* 代表这个类会被Spring接管,被注解的类,中所有方法,
* 如果返回值是String,并且具有页面可以跳转,那么就会被视图解析器解析
* */
@Controller
public class ControllerTest02 {
@RequestMapping("/test1")
public String test(Model model){
model.addAttribute("msg","ControllerTest02");
return "test";//会在视图解析器拼接成:/WEB-INF/jsp/test.jsp
}
@RequestMapping("/test2")
public String test2(Model model){
model.addAttribute("msg","Serein");
return "test";
}
}
3、test.jsp
页面和上面一样
4、配置tomcat运行
二、RestFul风格
1、概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
2、使用路径变量
例子:在上述配置的基础上,创建一个RestFulController.java
RestFulController.java
@Controller
public class RestFulController {
//原来的: http://localhost:8080/add?a=1&b=2
@RequestMapping("/add")
public String test(int a, int b, Model model){
int result=a+b;
model.addAttribute("msg","结果为"+result);
return "test";
}
这里直接访问 http://localhost:8080/add 是访问不到的,必须传参数
改进后:
public class RestFulController {
/*
在Spring MVC中可以使用 @PathVariable 注解,
让方法参数的值对应绑定到一个URI模板变量上。
*/
@RequestMapping( "/add/{a}/{b}")
public String test(@PathVariable int a,@PathVariable int b, Model model){
int result=a+b;
model.addAttribute("msg","结果为"+result);
return "test";
}
}
使用路径变量的好处?
- 使路径变得更加简洁;
- 获得参数更加方便,框架会自动进行类型转换。
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/commit/1/a,则路径与方法不匹配,而不会是参数转换失败。
3、使用method属性指定请求类型
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
例如:
public class RestFulController {
//只有相同的请求才能访问,否则访问不到
//method = RequestMethod.DELETE 限制请求为DELETE请求
@RequestMapping( value = "/add/{a}/{b}",method = RequestMethod.DELETE)
public String test(@PathVariable int a,@PathVariable int b, Model model){
int result=a+b;
model.addAttribute("msg","结果为"+result);
return "test";
}
}
再访问:
因为我们输入 http://localhost:8080/add/1/2 再回车,属于GET请求,但是我们限制请求类型为DELETE才能访问到,所以这里我们访问不到。
//限制请求为Get请求:
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
//或者
@GetMapping("/add/{a}/{b}")
//限制请求为POST请求
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.POST)
//或者
@PostMapping("/add/{a}/{b}")
//限制请求为PUT请求
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.PUT)
//或者
@PutMapping("/add/{a}/{b}")
//限制请求为DELETE请求
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.DELETE)
//或
@DeleteMapping("/add/{a}/{b}")
//等等....