回顾SpringMVC-02
上篇回顾了SpringMVC的概述,本篇讲讲SpringMVC的注解式开发、@Controller、@RequestMapping、数据处理等。
Controller
@Controller概述
在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。
@Controller定义Controller控制器
我们是用@Controller标记类以后他就是SpringMVC的控制器类了吗?怎么可能,Spring还不认识他呢,怎么让他俩认识?我们要把这个控制器交给Spring来管理,这里也有两种方式
1、在SpringMVC配置文件中定义**Controller的bean对象
<bean class="com.feng.controller.MyController"/>
2、在配置文件中告诉Spring应该到哪里找@Controller的Controller控制器
<context:component-scan base-package="com.feng.controller"/>
用@Controller来映射Request请求见下方
例子我们放在下面和RequestMapping一起举例
RequestMapping
@RequestMapping请求规则
通过@RequestMapping注解可以定义处理器对于请求的映射规则。该注解可以注解在方法上,也可以注解在类上,但意义是不同的。value属性值以"/"开始。
其实在SpringMVC中,这个RequestMapping更像是Servlet中在web.xml中配置的servlet-mapping,作用基本一致,就是通过他来指定控制器可以处理URL请求。
在RequestMapping源码里可以发现,在@Target中有两个属性,一个是方法一个是类的声明,表示@RequestMapping可以在方法和类的声明中使用。
其次在注解里面可以看到,除了name返回字符串,其他的方法都返回数组,也就是可以定义多个属性值,比如value()和path()都可以同时定义多个字符串值来接收多个URL请求
用@Controller来映射Request请求
这里我们举一个例子
编写controller业务代码
@Controller
@RequestMapping("/c3")
public class ControllerTest3 {
@RequestMapping("/t1")public String test1(Model model){
model.addAttribute("msg","test3333");return "test";}
}
记得在springmvc.xml配置文件里开启扫描
开启后
刚才在RequestMapping源码里看到这个注解还可以加method属性
@RequestMapping的method属性
method属性用于约束请求的类型,可以收窄请求范围。并且只有满足该method属性指定提交方式的请求,才会执行这个注解方法,否则会报错。
不难发现,Method 属性的取值为 RequestMethod 枚举常量。
包括GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE等请求词。
咱测一下:
写一个增加方法
@Controller
public class RestFulController {
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.POST)public String test1(@PathVariable int a,@PathVariable int b, Model model){
int res= a+b;model.addAttribute("msg","结果为"+res);return "test";}}
用错误的post来实现,浏览器输入http://localhost:8080/add/1/2
可以看到报了405错误,但是如果我们改成GET方法呢?
可以看到改成GET就正常了,其实在浏览器的地址栏请求里,默认的都是HttpGET类型的,在客户端浏览器常用的请求和提交方式有以下几种
No | 请求方式 | 提交方式 |
---|---|---|
1 | 表单请求 | 默认GET,可指定POST |
2 | AJAX请求 | 默认GET,可指定POST |
3 | 地址栏请求 | GET请求 |
4 | 超链接请求 | GET请求 |
5 | src资源路径请求 | GET请求 |
注意:
- 只要指定了处理器匹配的请求提交方式是POST,那就只能使用指定请求
- 如不指定method属性,那不管是GET还是POST提交方式,都可以匹配请求的提交方式
对于注解的变体还有几个组合注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
比如这里面的@GetMapping其实就是@RequestMapping(method =RequestMethod.GET) 的另一种表示的方法
数据处理
处理提交数据
1、提交的域名称和处理方法的参数名一致
提交数据:http://localhost:8080/c3/hello?name=feng
处理方法:
@RequestMapping("/hello")public String hello666(String name){
System.out.println(name);return "hello";}
后台输出
2、提交的域名称和处理方法的参数名不一致
提交数据:http://localhost:8080/c3/hello?username=feng
处理方法:
//@RequestParam("username") : username提交的域的名称 .@RequestMapping("/hello")public String hello667(@RequestParam("username") String name){
System.out.println(name);return "hello";}
后台输出
3、提交一个对象
要求提交的表单域和对象的属性名一致,参数使用对象即可
实体类如下
public class User {
private int id;private String name;private int age;//getset有无参略
}
提交数据:
http://localhost:8080/user/t2?name=feng&id=1&age=22
处理方法
@RequestMapping("/user")
public String user(User user){
System.out.println(user);return "hello";
}
后台输出
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
数据回显前端
ModelAndView
最常用的不必多说
//localhost:8080/user/t1?name=***;@GetMapping("/t1")public String test1(@RequestParam("name") String name, Model model){
//1、接受前端参数System.out.println("接收到前端的参数为:"+name);//2、将返回的结果传递给前端model.addAttribute("msg",name);//3、跳转视图return "test";}
数据传递中文乱码
如果传递参数时出现传递中文乱码,我们可以使用SpringMVC提供的过滤器,在web.xml中配置
<filter><filter-name>encoding</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>
</filter>
<filter-mapping><filter-name>encoding</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
ps:修改了xml文件需要重启服务器
或者自定义过滤器,在web.xml配置上即可~
一般为了防止乱码问题,平时在能设置编码的地方,都统一设置成UTF-8方便管理