一、常用注解
1. @RequestParam
作用:可以把请求参数传递给请求方法。
属性:
- value:请求参数中的名称。
- required:请求参数中是否必须提供此参数。默认值:true。表示请求参数中必须包含对应的参数,若不存在,将抛出异常。
/**
* @RequestParam 当表单name和形参列表名字不一致时,使用此注解。
* 属性:
* name:指定表单的name
* required:指定是否为必须
*/
@RequestMapping("/test1")
public String test1(@RequestParam(name = "name", required = false) String username, Integer myage) {
System.out.println(username + " " + myage);
return "success";
}
<form method="post" action="anno/test1">
<input type="text" name="name"/><br/>
<input type="text" name="age"/><br/>
<input type="submit" value="submit"/>
</form>
2. @RequestHeader
- 作用:请求头包含了若干个属性,服务器可根据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中。
3. @RequestBody
- 作用:用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。get 请求方式不适用。
- 属性:required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false,get 请求得到是 null。
/**
* @RequestBody 用于获取请求体内容
* 属性:
* 属性:
* required:指定是否为必须
* 当请求方式为get时,指定为true会报错,
* 指定为false时,拿到的是null。
*/
@RequestMapping("/test2")
public String test2(@RequestBody(required = false) String name) {
System.out.println(name);
return "success";
}
<form method="post" action="anno/test2">
<input type="text" name="name"/><br/>
<input type="submit" value="submit"/>
</form>
4. @PathVariable
作用:用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
属性:
- value:用于指定 url 中占位符名称。
- required:是否必须提供占位符。
<a href="anno/test3/张三">test3</a><br/>
/**
* @PathVariable restful风格,spring3.0新特性
* 以/参数方式传递参数
* 次注解的value属性指定传递的参数名
*/
@RequestMapping("/test3/{name}")
public String test3(@PathVariable("name") String name) {
System.out.println(name);
return "success";
}
5. @CookieValue
- 作用:@CookieValue 可让处理方法入参绑定某个 Cookie 值。
/*获取cookie信息*/
@RequestMapping(value = "/testcookie")
public String testMethodCookie(@CookieValue(value = "JSESSIONID",required = false) String ev){
System.out.println("JSESSIONID = "+ ev);
System.out.println("testMethodCookie方式执行了 >>>>>>>>>");
return "hello";
}
6. @DateTimeFormat
//@DateTimeFormat注解用来解决表单提交的日期数据类型转换问题,表单提交的字符串,加注解后,转化为日期类型。
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
private String birthday;
控制层
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
binder.registerCustomEditor(int.class, new IntegerEditor());
binder.registerCustomEditor(long.class, new LongEditor());
binder.registerCustomEditor(double.class, new DoubleEditor());
binder.registerCustomEditor(float.class, new FloatEditor());
}
或者:
@InitBinder
public void initBinder(WebDataBinder binder){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class,new CustomDateEditor(dateFormat,true));
}
7. @RequestHeader
作用:用于获取请求消息头。
属性:
- value:提供消息头名称。
- required:是否必须有此消息头
注意:在实际开发中一般不怎么用。
@RequestMapping("/test4")
public String test4(@RequestHeader(value = "Accept-Language", required = false) String value) {
System.out.println(value);
return "success";
}
<a href="anno/test4">test4</a><br/>
8. @CookieValue
作用:用于把指定 cookie 名称的值传入控制器方法参数。
属性:
- value:指定 cookie 的名称。
- required:是否必须有此 cookie。
@RequestMapping("/test5")
public String test5(@CookieValue(value = "JSESSIONID", required = false) String value) {
System.out.println(value);
return "success";
}
<a href="anno/test5">test5</a><br/>
9. @ModelAttribute
作用:该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
出现在参数上,获取指定的数据给参数赋值。
属性:
value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的key。
应用场景:当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
例如:我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
/**
* @ModelAttribute
* 1.夹在方法上:
* 1.没有返回值
* 可以应用在从表单获取的值不全,在返回方法前先给其将值补全
* 2.有返回值
* 可以根据表单提交的一个值在到达控制层之前先去从数据库查询,
* 严重怀疑这个方法利用动态代理对方法进行增强。
* 2.加在方法参数上:
* 可以为指定的属性赋值
*/
@RequestMapping("/test6")
public String test6(User user) {
System.out.println(user.getName() + "..." + user.getAge());
return "success";
}
@ModelAttribute
public void test11(User user){
System.out.println(user.getName()+" "+user.getAge()+"......");
user.setAge(20);
}
<form action="anno/test6">
<input type="text" name="name"/><br/>
<input type="submit" value="submit"/>
</form>
场景二:
@RequestMapping("/test6")
public String test6(User user) {
System.out.println(user.getName() + "..." + user.getAge());
return "success";
}
@ModelAttribute
public User test22(String name) {
//模拟从数据库查询数据
User user=findUserByname(name);
return user;
}
//模拟服务层dao层方法
private User findUserByname(String name) {
User user = new User();
user.setName(name);
user.setAge(20);
return user;
}
<form action="anno/test6">
<input type="text" name="name"/><br/>
<input type="submit" value="submit"/>
</form>
场景三
//模拟服务层dao层方法
private User findUserByname(String name) {
User user = new User();
user.setName(name);
user.setAge(20);
return user;
}
@RequestMapping("/test7")
public String test7(@ModelAttribute(value="1") User user){
System.out.println(user);
return "success";
}
@ModelAttribute
public void test33(String name, Map<String,User>map){
//模拟从数据库查询
User user=findUserByname(name);
map.put("1",user);
}
<form action="anno/test7">
<input type="text" name="name"/><br/>
<input type="submit" value="submit"/>
</form>
10. @SessionAttribute
作用:用于多次执行控制器方法间的参数共享。
属性:
- value:用于指定存入的属性名称
- type:用于指定存入的数据类型
<a href="session/put">put</a><br/>
<a href="session/get">get</a><br/>
<a href="session/delete">delete</a><br/>
@Controller
@RequestMapping("/session")
@SessionAttributes(value = {"name","age"})
public class Session {
/**
* 存入Session
* Model 是 spring 提供的一个接口,该接口有一个实现类 ExtendedModelMap
* 该类继承了 ModelMap,而 ModelMap 就是 LinkedHashMap 子类
*/
@RequestMapping("/put")
public String put(Model model){
model.addAttribute("name","尹会东");
model.addAttribute("age",23);
return "success";
}
/**
* 取出Session
*/
@RequestMapping("/get")
public String get(ModelMap map){
System.out.println(map.get("name"));
System.out.println(map.get("age"));
return "success";
}
/**
* 清除Session
*/
@RequestMapping("/delete")
public String delete(SessionStatus status){
status.setComplete();
return "success";
}
}
11. Restful风格
什么是Restful
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 更新,POST
- http://localhost/item/deleteItem.action?id=1 删除,GET或POST
使用Restful操作资源:可以通过不同的请求方式来实现不同的效果,如下:请求地址一样,但是功能可以不同。
- http://localhost/item/1 查询,GET
- http://localhost/item/ 新增,POST
- http://localhost/item/ 更新,PUT
- http://localhost/item/1 删除,DELTETE
HiddenHttpMethodFilter:浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。
@Controller
public class RestfulController {
//原来的:http://localhost:8080/add?d=1&b=2
//Restful:http://localhost:8080/add/1/2
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
// @GetMapping("/add/{a}/{b}")
public String test1(@PathVariable int a ,@PathVariable String b , Model model){
String num = a +b;
model.addAttribute("msg","结果是:"+num);
return "test";
}
}
@GetMapping是一个组合注解。
他相当于 @RequestMapping(method =RequestMethod.GET)
二、响应数据和结果视图
1. JSON
https://blog.csdn.net/weixin_45606067/article/details/107612827
2. 处理模型数据
Spring MVC 提供了以下几种途径输出模型数据:
- ModelAndView:处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据
- Map 及 Model:入参 为 org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
- @SessionAttributes:将模型中的某个属性暂存到 HttpSession 中,以便多个请求之间可以共享这个属性。
- @ModelAttribute:方法入参标注该注解后,入参的 对象就会放到数据模型中。
3. 返回值分类
1)void
通过设置ServletAPI,不需要视图解析器。
- 通过HttpServletResponse进行输出。
- 通过HttpServletResponse实现重定向。
- 通过HttpServletRequest实现转发。
@Controller
public class ResultGo {
@RequestMapping("/result/t1")
public String test1(HttpServletRequest req,HttpServletResponse resp) throws Exception{
//普通
resp.getWriter().write("json 串");
//响应 json 数据
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write("json 串");
}
@RequestMapping("/result/t2")
public String test1(HttpServletRequest req,HttpServletResponse resp) throws Exception{
resp.sendRedirect("/index.jsp");
}
@RequestMapping("/result/t3")
public String test1(HttpServletRequest req,HttpServletResponse resp) throws Exception{
req.setAttribute("msg","/result/t3");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
}
}
2)ModelAndView
ModelAndView 是 SpringMVC 为我们提供的一个对象,该对象也可以用作控制器方法的返回值。
返回值如果为 ModelAndView, 则其既 包含视图信息,也包含模型数据信息。
@Controller
public class ControllerTest3 {
@RequestMapping("/test1")
public ModelAndView test1(){
//ModelAndView 模型和视图
ModelAndView mv =new ModelAndView();
//封装对象,放在ModelAndView中
mv.addObject("msg","HelloSpringMVC!!!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello");
return mv;
}
}
3)Model、ModelMap
forward转发
转发地址栏不会改变。
controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。
需要注意的是,如果用了 forward:则路径必须写成实际视图 url,不能写逻辑视图。
它相当于“request.getRequestDispatcher(“url”).forward(request,response)”。使用请求转发,既可以转发到 jsp,也可以转发到其他的控制器方法。
return "forward:/WEB-INF/jsp/success.jsp";//没有视图解析器,则需要写完整的路径。
return "success";//如果有视图解析器。默认就是请求转发。
return "forward:/user/findAll";//也可以转发路径
Redirect重定向
重定向地址栏发生改变。
controller 方法提供了一个 String 类型返回值之后,它需要在返回值里使用 redirect: 。
它相当于“response.sendRedirect(url)”。需要注意的是,如果是重定向到 jsp 页面,则 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。
return "redirect:/add.jsp";//可以重定向页面。
return "redirect:/user/findAll.do";//也可以重定向路径。
代码测试:
@Controller
@RequestMapping("/return")
public class returnController {
/**
* 返回值类型为String,在request作用于存放值,并显示到页面
*/
@RequestMapping("/string")
public String test1(Model model){
model.addAttribute("name","张三");
model.addAttribute("age",22);
return "success";
}
/**
* 关键字:forward和redirect
*/
@RequestMapping("/fr")
public String test4(){
System.out.println("..................");
//return "forward:/WEB-INF/views/success.jsp";
return "redirect:/index.jsp";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>return</title>
</head>
<body>
<h3>return返回值类型</h3>
<a href="return/string" >string</a><br/>
<a href="return/fr" >fr</a><br/>
</body>
</html>
4)@SessionAttributes【了解】
- 若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC 将在模型中对应的属性暂存到 HttpSession 中。
- @SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
- @SessionAttributes(types=User.class) 会将隐含模型中所有类型 为 User.class 的属性添加到会话中。
- @SessionAttributes(value={“user1”,“user2”})
- @SessionAttributes(types={User.class, Dept.class})
- @SessionAttributes(value={“user1”, “user2”},types={Dept.class})
5)@ModelAttribute
- 在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。
简单来说:@ModelAttribute 标注方法上,当访问Controller中 任何一个方法时,都会先经过此方法。 - 在方法的 入参前使用 @ModelAttribute 注解 :
- 可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象中,再传入入参
- 将方法入参对象添加到模型中
- 被@ModelAttribute注释的方法会在此 controller 每个方法执行前被执行,因此对于一个 controller 映射多个URL的用法来说,要谨慎使用。
<a href="<%=request.getContextPath()%>/testattr" >test ModelAndView</a> <br/>
<hr/>
<form action="testuser" method="post">
name:<input type="text" name="name" value="jim" /><br/>
age:<input type="text" name="age" value="20" /><br/>
<input type="submit" value="test" />
</form>
@Controller
public class HelloController {
/**
* @ModelAttribute 标注方法上 , 当访问Controller中 任何一个方法时,都会先经过此方法
*/
@ModelAttribute
public void modelAttributetest(){
System.out.println("进入到 标注了@ModelAttribute 的方法中");
}
@RequestMapping( value="/testattr")
public String test2( Model m ){
System.out.println("进入到 controller");
User u = new User();
u.setName("tom");
u.setAge(23);
m.addAttribute("key", u);
return "hello" ;
}
/**
* 方法标注的对象,会自动存入到request(模型)中, 默认的key 是对象的类名首字母小写
* 当需要不适用默认的 key 时 ,可是使用@ModelAttribute("p") Person per 来修改key
*/
@RequestMapping("/testuser")
public String test3(@ModelAttribute("p") Person per){
//request.setAttrbute("p",per);
System.out.println(per.getName() + " : " + per.getAge());
return "hello2";
}
}
hello2.jsp
<h1>你好Springmvc</h1>
<%
Person p = (Person)request.getAttribute("p");
name:<%= p.getName() %> age: <%= p.getAge() %>
%>
6)@ResponseBody 注解响应json数据
作用:该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如:json,xml 等,通过 Response 响应给客户端。
DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置:<mvc:resources>
标签配置不过滤。
属性:
- location元素表示webapp目录下的包下的所有文件。
- mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b。
使用@RequestBody获取请求体数据。
使用@RequestBody注解把json的字符串转换成JavaBean的对象。
使用@ResponseBody注解把JavaBean对象转换成json字符串,直接响应json字符串和JavaBean对象互相转换的过程中,需要使用jackson的jar包。
代码演示:
@Controller
@RequestMapping("/ajax")
public class Ajax {
/**
* 发送Ajax异步请求
* 1.静态资源处理:在配置文件中加入<mvc:resource />标签,指定放行的资源。
* 2.导入jackson的依赖
* 3.
* @RequestBody
* 接受请求体消息
* @ResponseBody
* 发送响应体消息
* 4.springmvc框架已经为我们封装好了处理json数据的方法,底层会自动执行。
*/
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){
System.out.println("testAjax");
System.out.println(user);
//模拟数据建库查询
user.setUsername("haha");
user.setAge(40);
//做响应
return user;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
//页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
//alert("hello btn");
//发送ajax请求
$.ajax({
//编写json格式,设置属性和值
url:"user/testAjax",
contentType:"application/json;charset=UTF-8",
data:'{"username":"hehe","password":"123","age":30}',
dataType:"json",
type:"post",
success:function (data) {
//data服务器相应的json的数据,进行解析
alert(data);
alert(data.username);
alert(data.password);
alert(data.age);
}
});
});
});
</script>
</head>
<body>
<button id="btn">发送ajax</button>
</body>
</html>
如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客