单单使用@Controller 标记在一个类上还不能真正意义上的说它就是SpringMVC 的一个控制器类,因为这个时候Spring 还不认识它。那么要如何做Spring 才能认识它呢?这个时候就需要我们把这个控制器类交给Spring 来管理.
有两种方法,配置完成后就可以直接在类名上使用@Controller注解了
(1)在SpringMVC 的配置文件中定义MyController 的bean 对象 (只对MyController类生效)。
<bean class="com.springmvc.controller.MyController"></bean>
(2)在SpringMVC 的配置文件中告诉Spring 该到哪里去找标记为@Controller 的Controller 控制器。
开启注解扫描,扫描com.springmvc包下的所有注解(推荐)
<context:component-scan base-package="com.springmvc"></context:component-scan>
要使注解生效还需开启注解支持
<!--开启springMVC框架注解的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
(一) value,path 指定请求的实际地址,value和path作用一样
@RequestMapping(path = "/user")
(二) method 指定请求的method类型, 只有指定的类型请求才能访问该控制层方法,默认值为get请求
//设定只有post请求才能请求到被注解的控制层方法
@RequestMapping(value = "/saveAccount",method = RequestMethod.POST)
请求类型有GET、POST、PUT、DELETE等
(三) consumes,produces
在Request中
ContentType 用来告诉服务器当前发送的数据是什么格式 Accept 用来告诉服务器,客户端能认识哪些格式,最好返回这些格式中的其中一种 consumes 用来限制ContentType produces 用来限制Accept
举例: 有个用户发了一个请求, 请求头中 ContentType =application/json Accept = */ * 就是说用户发送的json格式的数据,可以接收任意格式的数据返回
//设定控制层方法返回json数据
@RequestMapping(value = "/test", method = RequestMethod.GET, produces="application/json")
//设定控制层方法仅处理request Content-Type为“application/json”类型的请求。
@RequestMapping(value="/test", method = RequestMethod.POST, consumes="application/json")
(四) params,headers
//限制只有网址后面拼接/findAccount?accountId=233的请求,才能访问该控制层
@RequestMapping(path = "/findAccount",params = {"accountId=233"})
//限制只有网址后面拼接/removeAccount?accountName=222&&money>100的请求,才能访问该控制层
//传的accountName参数可以为任意值
@RequestMapping(value="/removeAccount",params= {"accountName","money>100"})
//限制Request Headers中必须有Host=localhost:8080值的请求才能访问控制层方法
@RequestMapping(path = "/hello",headers = "Host=localhost:8080")
主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter("name") ,实现参数绑定 它有三个常用参数:defaultValue = "0", required = false, value = "paramName";
defaultValue 表示设置默认值,required 通过boolean设置是否是必须要传入的参数,value 值表示接收的传入的参数名称。
@RequestMapping("test1")
//name的值不传默认为测试
public String test1(@RequestParam(defaultValue = "测试",value="name") String username)
{
System.out.println(username);
return "success";
}
<a href="test1?name=">test1</a>
属性值: required:是否必须有请求体。默认值是:true。当取值为true时,get请求方式会报错。如果取值为false,get请求得到是null。
前端页面:
<body>
<form action="test/test1" method="post">
<p>RequestBody注解post方法</p>
用户名称:<input type="text" name="username" ><br/>
用户密码:<input type="password" name="password" ><br/>
用户年龄:<input type="text" name="age" ><br/>
<input type="submit" value="保存"><br/>
</form>
</body>
后端控制层方法:
@Controller
@RequestMapping("test")
public class test {
@RequestMapping(path="test1")
public String useRequestBody(@RequestBody(required=true) String body){ System.out.println(body);//可打印出前端提交的post数据,形式是key=value
return "success";
}
}
属性值: value:提供消息头名称 required:是否必须有此消息头
/*获取请求头中Referer的值,也就是当前打开的网址*/
@RequestMapping(path="RequestHeader")
public String useRequestHeader
(@RequestHeader(value = "Referer",required=true) String a){
System.out.println(a);//打印请求头中Referer的值
return "success";
}
被@ModelAttribute注释的方法会在此controller每个方法执行前被执行 ; 因此对于一个controller映射多个URL的用法来说,要谨慎使用。
Spring mvc在调用目标方法前,会先逐个调用方法级别上的标注了@ModelAttribute的方法,并将方法的返回值添加到模型中(模型中对应的key默认为返回值类型小写)
(1)@ModelAttribute注释void返回值的方法(可用来传递一些必须的参数,在其它控制器方法也能调用)
以下前端链接传递了userName=xsh参数,请求test/test1路径的控制层方法
<a href="test/test1?userName=xsh">test1</a>
后端控制层方法 :
@Controller
@RequestMapping("test")
public class test {
@ModelAttribute
//接收前端传递的userName值,并储存到model中
public void test(@RequestParam String userName,Model model){
model.addAttribute("name",userName);
}
@RequestMapping("test1")
public String test1(ModelMap modelMap){
//modelMap.get(“”)可获取模型中的值,返回一个Object对象值
String a = (String) modelMap.get("name");
System.out.println(a);
return "success";
}
}
(2)@ModelAttribute注释返回具体类的方法
以下前端链接传递了userId=3参数,请求test/test1路径的控制层方法
<a href="test/test1?userId=3">test1</a>
后端控制层方法 :
@Controller
@RequestMapping("test")
public class test {
@Autowired
private UserService userService;//自动注入service层方法
//这种情况,ModelAttribute属性的名称没有指定,它由返回类型隐含表示,如这个方法返回User类型,那么这个ModelAttribute属性的名称是user。
@ModelAttribute
public User test(@RequestParam int userId){//@RequestParam可省略
return userService.find(userId);//接收前端传递的用户id,并调用service层方法根据id查询用户
}
//@ModelAttribute注释一个方法的参数,表示去模型中根据key获取相应的value,并赋值
//此时如果方法体没有标注@SessionAttributes("user"),那么scope为request;如果标注了,那么scope为session
@RequestMapping("test1")
public String test1(@ModelAttribute("user")User a){//获取模型中key=user的value,并赋值给a
System.out.println(a);
return "success";
}
}
(3)@ModelAttribute(value="")指定属性名称
@Controller
@RequestMapping("test")
public class test {
@Autowired
private UserService userService;//自动注入service层方法
//使用@ModelAttribute注释的value属性,来指定model属性的名称
@ModelAttribute(value="aaa")
public User test(@RequestParam int userId){//@RequestParam可省略
return userService.find(userId);//接收前端传递的用户id,并调用service层方法根据id查询用户
}
@RequestMapping("test1")
public String test1(@ModelAttribute("aaa")User a){//获取模型中aaa的值,并赋值给a
System.out.println(a);
return "success";
}
}
默认情况下Spring MVC将模型中的数据存储到request域中。当一个请求结束后,数据就失效了。如果要跨页面使用,多个请求之间共享某个模型数据,那么需要使用到session。而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中。
SessionAttributes有三个属性值
1、names:这是一个字符串数组。里面应写需要存储到session中数据的名称。
2、types:根据指定参数的类型,将模型中对应类型的参数存储到session中
3、value:其实和names是一样的。
后端控制层:
@Controller
@RequestMapping("test")
@SessionAttributes(types = Integer.class)//将模型中int类型的数据储存到session中
public class test {
@RequestMapping("test1")
public String test1(Map<String,Object> map){
map.put("name","test");
map.put("age",18);
return "success";
}
}
success.jsp:
<body>
<h3>成功,success!</h3>
request中name: ${requestScope.name}<br/>
request中age: ${requestScope.age}<br/>
<hr/>
session中name: ${sessionScope.name}<br/>
session中age: ${sessionScope.age }<br/>
</body>
运行结果: 因为session被设置为只接收模型中int类型的值,所以name没有被储存到session中
@Controller
@RequestMapping("test")
@SessionAttributes(value ={"username","password"})
public class test {
@RequestMapping("/testPut")
public String testPut(Model model){
//将值存入模型中,因为在类上注解了@SessionAttributes,所以是存入session中
model.addAttribute("username", "test");
model.addAttribute("password","123456");
return "success";
}
@RequestMapping("/testGet")
public String testGet(ModelMap model){
//获取值
Object name = model.get("username");
Object pwd = model.get("password");
System.out.println(name+","+pwd);
return "success";
}
@RequestMapping("/testClean")
public String complete(SessionStatus status){
status.setComplete();//清除session中的值
return "success";
}
}
属性值: value:用于指定url中占位符名称。 required:是否必须提供占位符。
前端请求网页:
<a href="test/test1/10">test1</a>
后端控制器方法:
@Controller
@RequestMapping("test")
public class test {
@RequestMapping("test1/{id}")
public String test1(@PathVariable(value = "id",required = false) int a)
{
System.out.println(a);//输出10
return "success";
}
}
属性值: value:指定cookie的名称。 required:是否必须有此cookie。
@RequestMapping(path="CookieValue")
public String useCookieValue
(@CookieValue(value = "JSESSIONID",required=true) String a)
{
System.out.println(a);//获取JSESSIONID的值并打印
return "success";
}
评论