SpringMVC注解开发(RESTFul)
-
REST的概念
- 表现状态转移(Representational State Transfer,缩写:REST)。这并非一项新技术,而是现在互联网比较流行的一种软件架构。
- 资源(Resource):网络中的实体。可以理解为网络中的文本,图片,影音,可以通过URI(统一资源标识)指向资源。
- 表现(Representational):资源呈现的形式。如:文本,HTML,XML,JSON
- 状态转移(State Transfer):客户端向服务器发送请求,HTTP协议是无状态的,我们需要一种新的机制来进行状态改变。(GET,POST,PUT,DELETE…)
- RESTFul: REST的风格,方式。
-
注解的方式开发
- 参考https://github.com/fxyh9712/SpringStudy/tree/master/SpringMVC03
-
注解的详解
-
@Controller
- 通过
<context:component-scan base-package="com.fxyh.springmvc.web.controller"/>
扫描 - 表示这个类是控制器
- 通过
-
@RequestMapping
-
请求到后端控制器的一种映射策略
-
属性:
-
value():请求路径。和path()一样
-
method():
-
public enum RequestMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE }
-
-
-
-
@GetMapping
-
@RequestMapping(method = RequestMethod.GET) public @interface GetMapping { ... }
-
-
@PostMapping
-
@RequestMapping(method = RequestMethod.POST) public @interface PostMapping { ... }
-
-
@PathVariable
-
路径变量。一般在请求地址为:
/{id}/delete
的形式下使用。将{id}中的id值注入到方法的参数中,从而进行删除操作 -
注意:
-
@RequestMapping("/{uid}/delete") public String delete(@PathVariable(value = "uid") Integer id){ userService.deleteUser(id); return "redirect:/user/findAll"; }
-
在{}里的名称和参数名一致的时候,可以不用写value,但是如果像上面的情况,就必需写value=“uid”
-
-
-
@RequestParam
- 这个和上面那个PathVariable注解的value一样,当参数名和前段传过来的参数名不一致的时候使用。
-
@RequestBody
- 客户端向服务器发送请求,SpringMVC内部会将请求通过HttpMessageConverter接口将读取的数据转换成JSON或XML。
-
@ResponseBody
-
服务器计算出结果(Java对象)自动转换成JSON对象,然后发送到客户端上去,客户端就可以进行解析
-
这个在开发中用得特别多
-
必需导入Jackson的jar(三个)
-
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.8</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.8</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
-
示例
-
package com.fxyh.springmvc.web.controller; import com.fxyh.springmvc.domain.Person; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller @RequestMapping("/ajax") public class AjaxController { @GetMapping("/test") public String test(){ return "ajax/test"; } @PostMapping("/test") @ResponseBody public Object test(@RequestBody Person person){ return person; } }
-
package com.fxyh.springmvc.domain; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = -1825456654722504660L; private String username; private Integer age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "username='" + username + '\'' + ", age=" + age + '}'; } }
-
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>ajax</title> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jQuery.js"></script> </head> <body> <button type="button" οnclick="send()">请求</button> <script type="text/javascript"> function send() { var person = {username: 'zhamgsan', age: 18}; $.ajax({ type: 'post', url: '${pageContext.request.contextPath}/ajax/test', contentType: 'application/json;charset=utf-8', data: JSON.stringify(person), success: function (data) { alert(data.username+'---------'+data.age) } }); } </script> </body> </html>
-
-
方法传入的参数使用该注解,这个参数的对象就会放到数据模型中(Model)
-
package com.fxyh.springmvc.web.controller; import com.fxyh.springmvc.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.Map; @Controller @RequestMapping("/model") public class ModelController { /** * 默认将user对象放入到Model中,key为方法名(user) */ @ModelAttribute public User user(){ User user = new User(); user.setId(100); user.setUsername("zhangsan"); return user; } @GetMapping("/test") @ResponseBody public User test(Model model){ User user = (User) model.asMap().get("user"); System.out.println(user); return user; } @GetMapping("/test2") @ResponseBody public User test2(Map map){ User user = (User) map.get("user"); System.out.println(user); return user; } }
-
在通一个Controller中可以有多个@ModelAttribute注解的方法,并且使用这个注解的方法一定会在@RequestMapping之前调用。
-
使用这个注解也可以在方法参数中传入Model,然后再Model设置属性的方式,上面的是另外一种方式。
-
package com.fxyh.springmvc.web.controller; import com.fxyh.springmvc.domain.User; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.util.Map; @Controller @RequestMapping("/model") @SessionAttributes(value = "user") public class ModelController { // ...上面的方法 @GetMapping("/test3") public String test3(@ModelAttribute User user){ user.setUsername("李四"); return "redirect:/model/test4"; } @GetMapping("/test4") @ResponseBody public Object test4(Model model){ User user = (User) model.asMap().get("user"); System.out.println(user); return user; } }
-
这里@ModelAttribute用在参数上和@SessionAttributes(value = “user”)结合使用的时候,访问test3的时候,会把user设置到session中,然后重定向到test4的时候,取到的user就是session中的李四,同样访问test,test2都是取到session中的值。
-
-
参数绑定
-
默认支持的参数类型
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Model
- addAttribute():相当于设置了request范围的属性。如果重定向,则取不到这些属性,但是会将这些属性拼成地址栏的参数
- 基本数据类型
- Integer
- Long
- Boolean
- String
- 等等
-
自定义对象
-
对于日期类型,需要编写自定义转换器,然后需要注册到HandlerAdapter中。
-
可以使用mvc命名空间简化
-
<!-- mvc:annotation-driven RequestMappingHandlerAdapter 给handlerAdapter注册转换器 --> <mvc:annotation-driven conversion-service="conversionService"/> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.fxyh.springmvc.converter.CustomDateConverter"> <property name="patterns"> <array> <value>yyyy-MM-dd</value> <value>yyyy/MM/dd</value> </array> </property> </bean> </set> </property> </bean>
-
-
-
数组
-
@PostMapping("/test") public String test(String[] arr, Model model){ model.addAttribute("arr", arr); return "array/test_return"; }
-
数组可以直接注入
-
-
集合
-
@PostMapping("/test") public String test(CollectionVO collectionVO, Model model){ model.addAttribute("collectionVO", collectionVO); return "collection/test_return"; }
-
package com.fxyh.springmvc.vo; import java.io.Serializable; import java.util.List; public class CollectionVO implements Serializable { private static final long serialVersionUID = -7912633966781257553L; List<String> collection; public List<String> getCollection() { return collection; } public void setCollection(List<String> collection) { this.collection = collection; } }
-
集合需要创建一个VO,否则不能注入。
-
-