本篇博文的目标是使用前端页面渲染插件jsRender做前后端分离,后端采用Spring MVC给出REST API,并结合Nginx完成配置。
结构如下图所示:
注: 前后端分离的做法很多,这里只是使用jsRender而已,本文不会讨论为什么不使用vue等。
在一步一步完成如上目标之前,先来看看什么是jsRender。
jsRender是基于Jquery的一个前端页面渲染插件。可以做到前后端口分离,前端通过ajax请求后台数据,后台拿到响应请求,返回Json格式的数据,然后前端通过 JsRender插件对json数据进行渲染达到前后端分离(后台只管传Json数据,前端Jsrender渲染数据)。 可以去官网获取更多的信息【http://www.jsviews.com/】
二、前端页面准备
其内容如下:
<!DOCTYPE html>
<!-- To run the current sample code in your own environment, copy this to an html page. -->
<html>
<head>
<script src="../js/jquery-1.12.4.min.js"></script>
<script src="../js/jsviews.js"></script>
</head>
<meta charset="utf-8"/>
<body>
<div id="result"></div>
<table>
<thead><tr><th>名字</th><th>愛好</th></tr></thead>
<tbody id="userListTable"></tbody>
</table>
<script id="usersTemplate" type="text/x-jsrender">
<tr>
<td>{{>name}}</td>
<td>
{{props hobbies}}
<div>
<b>{{>key}}</b>: {{>prop}}
</div>
{{/props}}
</td>
</tr>
</script>
<script type="text/javascript">
$.ajax({
type: "POST",
url: "../user/list",
dataType: "json",
success: function (data) {
$("#userListTable").html(
$("#usersTemplate").render(data)
);
}
});
</script>
</body>
</html>
从上述简单示例中,可以看出,表格内容是通过Ajax请求从后端获取的,格式为JSON,本文的示例,后台的REST API采用Spring MVC完成。
三、后端REST API准备
3.1 Spring MVC结构
3.2 User.java
User用户类,包含名字、年龄和爱好的属性。
package com.xxx.tutorial.demo.model;
import java.io.Serializable;
import java.util.List;
/**
*
* @author wangmengjun
*
*/
public class User implements Serializable {
private static final long serialVersionUID = -8725858518508034119L;
private String name;
private int age;
private List<String> hobbies;
public User() {
super();
}
public User(String name, int age, List<String> hobbies) {
super();
this.name = name;
this.age = age;
this.hobbies = hobbies;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age
* the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return the hobbies
*/
public List<String> getHobbies() {
return hobbies;
}
/**
* @param hobbies
* the hobbies to set
*/
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", hobbies=" + hobbies + "]";
}
}
用户服务接口 -- 用户定义接口方法。
package com.xxx.tutorial.demo.service;
import java.util.List;
import com.xxx.tutorial.demo.model.User;
/**
*
* @author wangmengjun
*
*/
public interface UserService {
List<User> findAllUsers();
}
package com.xxx.tutorial.demo.service.impl;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Service;
import com.xxx.tutorial.demo.model.User;
import com.xxx.tutorial.demo.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Override
public List<User> findAllUsers() {
return Arrays.asList(new User("Eric", 20, Arrays.asList("篮球", "跑步")),
new User("Wang", 21, Arrays.asList("爬山")));
}
}
用户控制器类如下:
package com.xxx.tutorial.demo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.xxx.tutorial.demo.model.User;
import com.xxx.tutorial.demo.service.UserService;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/list")
public ResponseEntity<List<User>> findAllUsers() {
List<User> users = userService.findAllUsers();
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}
}
本文使用的Nginx版本为1.11.7
配置动静分离,可以通过修改conf目录下的nginx.conf完成。
4.1 配置静态页面
指定js、css、html以及图片静态文件都从静态目录中获取。
#静态资源
location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp)$ {
root F:/static-pages/; # 站点根目录
index index.html index.htm;
}
添加upstream以及proxy_pass
动静规则配置后,配置文件如下图所示:
upstream tomcat{
server localhost:8082;
}
server {
listen 19000; # 监听本机所有 ip 上的 80 端口
server_name _; # 域名:www.example.com 这里 "_" 代表获取匹配所有
#静态资源
location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp)$ {
root F:/static-pages/; # 站点根目录
index index.html index.htm;
}
# 反向代理
location / {
proxy_pass http://tomcat;
}
自此,前端代码、后端RESTAPI代码以及Nginx配置都完成了,接下来,就可以测试一下。
五、测试一下
5.1 启动tomcat
将hello-springmvc工程,部署到tomcat/webapps/ROOT目录下, 如
启动:
5.2 启动Nginx
5.3 测试
浏览器输入http://localhost:19000/demo/index.html
显示的内容,正是我们REST API返回的内容。UserServiceImpl中的方法内容如下:
package com.xxx.tutorial.demo.service.impl;
import java.util.Arrays;
import java.util.List;
import org.springframework.stereotype.Service;
import com.xxx.tutorial.demo.model.User;
import com.xxx.tutorial.demo.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Override
public List<User> findAllUsers() {
return Arrays.asList(new User("Eric", 20, Arrays.asList("篮球", "跑步")),
new User("Wang", 21, Arrays.asList("爬山")));
}
}
自此,一个简单的前后端分离,小工程就结束了。至于jsRender的详细信息,有兴趣的读者可以参考【http://www.jsviews.com/】,本文将不做讨论。