springmvc注解 | JSON | Restful | 结果视图

一、常用注解

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,不需要视图解析器。

  1. 通过HttpServletResponse进行输出。
  2. 通过HttpServletResponse实现重定向。
  3. 通过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> 标签配置不过滤。

属性:

  1. location元素表示webapp目录下的包下的所有文件。
  2. 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>

如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值