项目前后端总体框架搭建(创新实训日志四)

具体的业务逻辑在这里就不详细说了,主要来讲一下项目前后端的整体架构和其通讯问题。

1.项目整体架构:

后台利用springboot内嵌的tomcat作为服务器,负责业务逻辑的部分。

前台利用nginx作为服务器,负责数据展示的部分。

前后台利用Json结构的数据来进行通讯,数据格式如下:

{
	"code": 0,	//如果为0表示成功,如果大于0表示用户输入不符合条件,小于0说明为服务器内部错误
	"message": "success",	//如果code为0可以忽略这一项,不为0则直接提示这里的信息
	"object": [{	//如果code不为0则可以忽略这一项,否则从这里取出真实需要的数据
        ...
	}]
}

这里没有使用jsp或者thymleaf等框架来返回一个渲染后的页面,可以获得以下的优势:

  1. 前后端真正解耦,前后端可以各自开发,只需要利用协定接口进行通信即可。
  2. 更容易的发现bug,由于前后端可能的问题有各自特点,因此可以比较容易的定位bug。
  3. 减少后端服务器的压力,静态资源由nginx服务器获取到,后端只需要获取数据相关的动态资源。
  4. 接口易于重用,由于后端返回的数据是json字符串,因此即使以微信作为前端也只需要解析字符串并渲染即可,无需修改后端代码。

2.后台相关配置:

后台所要完成的是业务逻辑,具体来说就是从数据库中取出数据,进行一定的处理之后,以json字符串的形式返回给前台。

2.1.接口结构类定义:

package com.ctrl_i.springboot.dto;
import net.sf.json.JSONObject;
public class Envelope {
    private int code;//代码
    private String message;//提示信息
    private Object obj;//携带对象
    public static Envelope dbError=new Envelope(-1,"数据库错误!",null);//数据库错误
    public static Envelope systemError=new Envelope(-2,"系统错误!",null);;//系统错误
    public static Envelope success = new Envelope(0, "success", null);//成功
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Object getObj() {
        return obj;
    }
    public void setObj(Object obj) {
        this.obj = obj;
    }
    public Envelope(int code,String message,Object obj) {
        this.code=code;
        this.message=message;
        this.obj=obj;
    }
    public Envelope() {
    }

    public Envelope(Object obj) {
        this.code = 0;
        this.message = "success";
        this.obj = obj;
    }
    @Override
    public String toString(){
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("code",this.code);
        jsonObject.put("message",message);
        jsonObject.put("object",this.obj);
        return jsonObject.toString();
    }
}

定义一个接口结构类有助于减少重复的代码量,并且规范返回前端的数据格式。

2.2.业务逻辑层描述

这里以获取文章列表的功能为例:

2.2.1.dao层:

dao层用于从数据库中取出需要的数据。

@Repository
public class ArticleDaoImpl  extends BaseDaoImpl<Integer, ArticleEntity> implements ArticleDao {
    @Override
    public List<ArticleEntity> getOnePageArticleAfterId(int lastId, int pageSize) throws Exception {
        String hql="from ArticleEntity where id>? order by id desc";
        Object [] params={lastId};
        return executeHQL(hql,params,0,pageSize);
    }
}

2.2.2.service层:

service层调用dao层,将从其中取出的数据进行处理,并且将处理结果放入Envelope类中,返回类型为Envelope。

@Override
public Envelope getArticleList(int lastId) {
    List<ArticleEntity> list;
    try {
        list=articleDao.getOnePageArticleAfterId(lastId,PAGE_SIZE);
    } catch (Exception e) {
        e.printStackTrace();
        return Envelope.dbError;
   		... 省略部分逻辑
        jsonObject.put("readNum",articleEntity.getReadNum());   //阅读数
        jsonArray.add(jsonObject);
     }
     return new Envelope(jsonArray);
}

2.2.3.Controller层:

controller层调用service层,将从其中取出的Envelope类型序列化成字符串,然后通过http请求返回给前端,使其可以利用数据进行渲染。

/**
 * 获取一页文章列表
 * @param lastId 最后一条文章id
 * @return
 */
@RequestMapping("/list")
@ResponseBody
public String getArticleList(@RequestParam(name = "lastId",defaultValue = "0") int lastId){
    try{
        return articleService.getArticleList(lastId).toString();
    }catch (Exception e){
        return Envelope.systemError.toString();
    }
}

2.3.遇到的问题:

2.3.1.跨域问题:

在html页面中直接尝试获取后台的数据时,会提示跨域问题,通过查阅资料后发现这个问题很好解决,在Controller上添加一个注解即可:

@Controller
@CrossOrigin
@RequestMapping("/article")
public class ArticleController {

3.前端相关配置

3.1.nginx服务器配置

需要在nginx新加一个站点,并配置端口和项目根路径:

配置文件在/etc/nginx/site-available下

server {
	listen 8081; #default_server;
	listen [::]:8081; #default_server;
	root /home/zekdot/ctrl_i;
	index index.html index.htm index.nginx-debian.html;
	server_name _;
    error_page 404 /404.html;
	location / {
		try_files $uri $uri/ =404;
	}
}

这里将项目根目录配置在了/home/zekdot/ctrl_i下,静态资源以后都放在那里,同时设置端口为8081,即访问 localhost:8081就能够访问到静态资源。

配置好之后重启nginx服务器,然后尝试访问放置好在对应的路径下的页面:

1

可见配置成功。

3.2.页面间数据传递及后台数据获取

3.2.1.页面间数据传递

可以通过cookies、url等方式来进行数据的传递,最终选择了解析url的方式来获取传递的参数,因为如果用户禁止了cookies的使用的话那么第一种方式就行不通了。

这里首先实现一个解析url的函数:

function getParam(url){
    var url = url.split("?")[1];
    var para = url.split("&");
    var len = para.length;
    var res = {};
    var arr = [];
    for(var i=0;i<len;i++){
        arr = para[i].split("=");
        res[arr[0]] = arr[1];
    }
    return res;
}

然后在页面中传入url解析出 参数名-参数值 的键值对即可:

var url=window.location.search; //获取url 
id=getParam(url)['id']  //获取传过来的id

3.2.2.获取后台的数据

后台项目开启在8080端口上,因此只需要向这个端口请求数据即可,拿到数据之后再对页面进行填充。

/**
 * 用于填充页面
 */
function putArt(str){
	data=eval('('+str+')');
	if(data.code!=0){
		alert(data.message);
		return;
	}else{
    	arts=data.object
		var nodes=""
        ...省略部分逻辑
        nodes=$('<div class="blog-post-grids blog_grids></div>')
    }
}
/**
 * 得到下一页文章列表
 * @param lastId
 */
function getNextPage(lastId){
	$.post('http://121.250.213.120:8080/article/list',{'lastId':lastId},putArt);
}

最终得到的效果如下:

2

3

可见数据来源于后台的接口。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值