传统的mvc,view的生成其实是在服务器端生成的,或者页面跳转实在服务器端操纵的。
前后端分离,前后端之间的所有交互都是数据。前端自己实现路由,前端需要展示的数据则由后端提供。
之前做过车联网的一个项目。客户端有Android,iOS,PC客户端,浏览器等,使用的是Restful。当时刚毕业,知道这种模式强大,但却不知道这就是前后端分离的一个案例。如下图
rest简介
REST是一种交互方式,Restful则是符合rest原则的风格框架
无状态。每次请求不受上一次或者下一次请求影响
面向资源。这里的资源即数据,事实上,狭义的讲,就是一个URI。
如果一个架构复核REST原则,那么它就是一个Restful框架
共6中请求:PUT DELETE GET POST HEAD OPTIONS
如果URI相同,但是请求方式不同,那么处理的方法也不同
用uri定位资源,用http method定义操作
实现REST架构
1.前端统一返回json数据格式
1
{
2
success : true,
3
message:'',
4
code:'',
5
data : {}
6
}
2.后端统一对应的返回实体
1
2
import org.apache.ibatis.exceptions.TooManyResultsException;
3
4
import java.sql.SQLException;
5
/**
6
* 增删改时返回前端的判断实体
7
* @author Lihhz 2017-03-15
8
*
9
*/
10
public class ResponseState {
11
/**错误信息*/
12
protected String message;
13
/**错误编码*/
14
protected short code;
15
/**是否成功*/
16
protected boolean success;
17
/**返回数据*/
18
protected Object data;
19
20
public ResponseState() {
21
this.code = 0;
22
this.success = true;
23
this.data = null;
24
}
25
26
public ResponseState(String message) {
27
this.message = message;
28
}
29
30
public ResponseState(short code, String message) {
31
this.code = code;
32
this.message = message;
33
}
34
35
public ResponseState(boolean success, String message) {
36
this.success = success;
37
this.message = message;
38
}
39
40
public ResponseState(short code, boolean success, String message) {
41
this.code = code;
42
this.success = success;
43
this.message = message;
44
}
45
46
public ResponseState(Exception ex) {
47
this.code = -1;
48
this.success = false;
49
if (ex.getMessage() == null) {
50
this.message = "参数不正确或不完整";
51
} else if (ex.getCause() instanceof SQLException)
52
this.message = "服务器异常:执行数据库语句错误";
53
else if(ex.getCause() instanceof TooManyResultsException)
54
this.message = "应该查询出一条结果,但查询出多条结果.";
55
else
56
setMessage(ex.getMessage());
57
}
58
59
public String getMessage() {
60
return this.message;
61
}
62
63
public void setMessage(String message) {
64
if (message != null)
65
message = message.replace("\"", "'").replace('\r', '\0');
66
this.message = message;
67
}
68
69
public short getCode() {
70
return this.code;
71
}
72
73
public void setCode(short code) {
74
this.code = code;
75
}
76
77
public boolean getSuccess() {
78
return this.success;
79
}
80
81
public void setSuccess(boolean success) {
82
this.success = success;
83
}
84
85
public Object getData() {
86
return this.data;
87
}
88
89
public void setData(Object data) {
90
this.data = data;
91
}
92
93
public String toString() {
94
StringBuffer sbJson = new StringBuffer("{\"code\":");
95
sbJson.append(this.code).append(",\"message\":\"").append(this.message)
96
.append("\",").append("\"success\":").append(this.success)
97
.append("}");
98
return sbJson.toString();
99
}
100
}
3.数据格式转换
前端的json如何转化为后端的entity,后端的entity又如何转前端json
在spring mvc中提供一种转换方式
1
@ResponseBody
2
@RequestMapping(value = "/query", method = RequestMethod.POST)
3
public PageVO query(HttpServletRequest request) {
4
……
5
}
其中RequestBody负责前端数据转后端,而ResponseBody则反之。如果使用@RestController而不是@Controller则不需要在方法上使用ResponseBody。下边是RestController的源码
1
/*
2
* Copyright 2002-2014 the original author or authors.
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
16
17
package org.springframework.web.bind.annotation;
18
19
import java.lang.annotation.Documented;
20
import java.lang.annotation.ElementType;
21
import java.lang.annotation.Retention;
22
import java.lang.annotation.RetentionPolicy;
23
import java.lang.annotation.Target;
24
25
import org.springframework.stereotype.Controller;
26
27
/**
28
* A convenience annotation that is itself annotated with {@link Controller @Controller}
29
* and {@link ResponseBody @ResponseBody}.
30
* <p>
31
* Types that carry this annotation are treated as controllers where
32
* {@link RequestMapping @RequestMapping} methods assume
33
* {@link ResponseBody @ResponseBody} semantics by default.
34
*
35
* @author Rossen Stoyanchev
36
* @author Sam Brannen
37
* @since 4.0
38
*/
39
@Target(ElementType.TYPE)
40
@Retention(RetentionPolicy.RUNTIME)
41
@Documented
42
@Controller
43
@ResponseBody
44
public @interface RestController {
45
46
/**
47
* The value may indicate a suggestion for a logical component name,
48
* to be turned into a Spring bean in case of an autodetected component.
49
* @return the suggested component name, if any
50
* @since 4.0.1
51
*/
52
String value() default "";
53
54
}
55
在spring中配置jackson进行json的序列化操作
1
<bean id="dateFormat" class="java.text.SimpleDateFormat">
2
<constructor-arg value="yyyy-MM-dd HH:mm:ss" />
3
</bean>
4
5
<!-- 也可以自定义ObjectMapper继承自org.codehaus.jackson.map.ObjectMapper,做一些特殊处理。-->
6
<bean id="objectMapper" class="org.codehaus.jackson.map.ObjectMapper">
7
<property name="dateFormat" ref="dateFormat" />
8
</bean>
9
<!-- 注册RequestMappingHandlerMapping 和RequestMappingHandlerAdapter 两个bean。-->
10
<mvc:annotation-driven>
11
<mvc:message-converters>
12
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
13
<property name="objectMapper" ref="objectMapper">
14
</property>
15
</bean>
16
</mvc:message-converters>
17
</mvc:annotation-driven>
至此,一个简单的Restful风格的框架就搭建起来了。还有安全验证,异常处理,跨域等问题需要处理。