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(三个)
<dependency>
<groupId>com.fasterxml.jackson.core
</groupId>
<artifactId>jackson-core
</artifactId>
<version>2.9.8
</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core
</groupId>
<artifactId>jackson-annotations
</artifactId>
<version>2.9.8
</version>
</dependency>
<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>
@ModelAttribute
方法传入的参数使用该注解,这个参数的对象就会放到数据模型中(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 {
@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设置属性的方式,上面的是另外一种方式。
@SessionAttributes
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中的值。
参数绑定
默认支持的参数类型
HttpServletRequestHttpServletResponseHttpSessionModel
addAttribute():相当于设置了request范围的属性。如果重定向,则取不到这些属性,但是会将这些属性拼成地址栏的参数 基本数据类型
IntegerLongBooleanString等等
自定义对象
对于日期类型,需要编写自定义转换器,然后需要注册到HandlerAdapter中。
可以使用mvc命名空间简化
<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,否则不能注入。