经过前面的努力,我们已经有前后对接的条件。
1. 前台可以处理json数据
2. 后台可以输出json数据
本节中,我们将前台与后台进行对接。
# 解决端口冲突
javaee中的tomcat默认使用的为8080端口。在前台开的单元测试中,karma同时也需要使用8080端口。下面,让我们配置端口来规避这个端口冲突。
## 方法一:修改tomcat端口号
位置如下:
![https://box.kancloud.cn/fffd8a993b2d9d63a35df540df1ddac3_2902x318.png](https://box.kancloud.cn/fffd8a993b2d9d63a35df540df1ddac3_2902x318.png)
我们可以修改为8088,8089等端口.
修改完端口后
## 方法二:修改karma端口
我们在WebApp中找到test/karma.conf.js
![https://box.kancloud.cn/0a2e86371f2c3f18a4c828123eb4dd39_1604x244.png](https://box.kancloud.cn/0a2e86371f2c3f18a4c828123eb4dd39_1604x244.png)
我们还是可以修改为8088,8089等端口
修改后,我们ctrl+c终止grunt,然后重新输入grunt server启动服务。
无论是哪一种方法,都可以起到避免端口冲突的目的。
在教程中,我们采用更改karma.conf.js中的port选项来规避这个问题。比如我们修改为8081端口
> 在此,为了避免端口冲突。我们做个规定:1.eclipse + tomcat默认使用8080端口 2.karma 默认使用8081端口。 3.grunt自带的http服务,使用9000端口。 4.我们手动启用的http-server默认使用8088端口。
# 解决跨域问题
什么是跨域呢?
> [https://segmentfault.com/a/1190000000718840](https://segmentfault.com/a/1190000000718840)
为什么不允许跨域呢?
![https://box.kancloud.cn/bf58b35c5499a5b8084da374e74555dd_2020x576.png](https://box.kancloud.cn/bf58b35c5499a5b8084da374e74555dd_2020x576.png)
总结:无论是浏览器,还是服务器,从用户的安全角度出发,默认都是不允许进行跨域访问的。而我们前后端分离的思想,将来需要将前台和后台布署到不同的服务器上,前台和后台拥有不同的域名。前台将数据发送给不同域的后台,后台再数据返回不同域名的前台。这就避免不了跨域的问题。
## ServletResponseAware
在Struts中,我们使用实现`ServletResponseAware`接口的方法实现设置请求文件头,从而实现跨域目的。
[http://127.0.0.1:8088/struts2-core-apidocs/org/apache/struts2/interceptor/ServletResponseAware.html](http://127.0.0.1:8088/struts2-core-apidocs/org/apache/struts2/interceptor/ServletResponseAware.html)
继承后,我们实现其中的唯一的`setServletResponse(HttpServletResponse response)`方法
```
package com.mengyunzhi.javaee.action.teacher;
...
import org.apache.struts2.interceptor.ServletResponseAware;
...
public class Index extends ActionSupport implements ServletResponseAware{
...
@Override
public void setServletResponse(HttpServletResponse response) {
// 设置发送文件头:允许跨域的地址
response.setHeader("Access-Control-Allow-Origin", "*");
// 允许Credentials
response.setHeader("Access-Control-Allow-Credentials", "true");
// 允许的请求方法
response.setHeader("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
// 允许的请求头
response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
}
...
```
此时,我们再访问[http://127.0.0.1:8080/javaee/teacher/](http://127.0.0.1:8080/javaee/teacher/), 查看控制台的网络选项卡,然后找到这条请求,查看响应信息:
![https://box.kancloud.cn/2706994bd227a6a9ffef35a55414c699_782x236.png](https://box.kancloud.cn/2706994bd227a6a9ffef35a55414c699_782x236.png)
发现在响应的一栏中,增加了一项:Access-Control-Allow-Origin,值为*。当我们的浏览器接收到此项信息时,就不会提示非法跨域的提示了。
<hr />
```
package com.mengyunzhi.javaee.action.teacher;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.mengyunzhi.javaee.entity.Teacher;
import com.opensymphony.xwork2.ActionSupport;
public class Index extends ActionSupport implements ServletResponseAware{
/**
* 定义serialVersionUID,增强兼容性
*/
private static final long serialVersionUID = 1L;
// 教师列表 类型为List,每项均为Teacher。
private List<Teacher> teachers;
// 当前页
private int page = 1;
// 每页大小
private int pageSize = 2;
// 查询姓名
private String name = "";
// 显示接收到的page信息
public int getPage() {
return page;
}
// 接收请求的page信息
public void setPage(int page) {
this.page = page;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setTeachers(List<Teacher> teachers) {
this.teachers = teachers;
}
// V层在展示数据teachers的时候,将自动调用该方法
public List<Teacher> getTeachers() {
return teachers;
}
// 该execute方法将被自动调用, 方法的返回类型必须为String
public String execute() {
// 获取教师列表
// 未输入姓名,则查询所有信息
if (name.equals("")) {
teachers = Teacher.paginate(page, pageSize);
// 输入姓名,则进行模糊查询
} else {
teachers = Teacher.paginate(name, page, pageSize);
}
return SUCCESS;
}
@Override
public void setServletResponse(HttpServletResponse response) {
// 设置发送文件头:允许跨域的地址
response.setHeader("Access-Control-Allow-Origin", "*");
}
}
```
# 修改前台
现在,我们正式将前台中的url写入正式的信息
app/scripts/services/teacher.js
```
...
// 获取所有教师
var all = function(callback) {
// $http.get().then(function1(){}, function2(){}); 链式调用 then()中接收两个参数,类型均为function
$http.get('http://127.0.0.1:8080/javaee/teacher/').then(function success(response) {
// 数据成功返回
console.log(response);
var teachers = response.data.teachers;
callback(teachers);
}, function error(response) {
console.log('数据请求错误:');
console.log(response);
});
};
...
```
# 测试
此时,我们刷新 [http://localhost:9000/#!/teacher/](http://localhost:9000/#!/teacher/), 打开控制台,并注意网络选项卡,如果数据成功返回的话,相信你已经能看到数据表中的数据了。
- README
- 第一章:准备
- 第二章:Hello World!
- 第一节:查看工程文件
- 第二节:JDK、JRE与环境变量
- 第三节:index.jsp
- 第三章:Hello Struts
- 第一节:Web.xml
- 第二节:单入口
- 第三节:Hello Struts
- 第四节:触发C层
- 第四章:建立数据表
- 第一节:建立实体类
- 第二节:测试一
- 第三节:测试二
- 第四节:引入Hibernate
- 第五节:配置Hibernate
- 第六节:建立连接
- 第七节:实体类映射数据表
- 第八节:完善数据表
- 第五章:教师管理
- 第一节:增加数据--add
- 第二节:增加数据--save
- 1 获取传入数据数据
- 2 数据写入测试
- 3 对接C层
- 第三节:数据列表
- 1 获取数据
- 2 重构代码
- 3 C层对接--初始化
- 4 C层添加数据
- 5 V层显示数据
- 6 获取数据库中数据
- 7 显示性别
- 8 分页
- 9 条件查询
- 第四节:修改数据
- 1 edit
- 2 update
- 第五节:删除数据
- 第六节:总结
- 第六章:重构C层
- 第一节:继承ActionSupport类
- 第二节:数据验证
- 第七章:前台分离(前台)
- 第一节:环境搭建
- 第二节:运行环境
- 第三节:共享开发环境
- 第四节:生产环境
- 第八章:前台开发(前台)
- 第一节:本地化
- 第二节:教师列表
- 1 引入M层
- 2 模拟后台返回数据
- 3 C与M对接
- 4 C与V对接
- 第九章:前后台对接(前后台)
- 第一节:后台输出json(后台)
- 第二节:对接前台(全栈)
- 第二节:对接API(前台)
- 第二节:跨域请求(后台)
- 第三节:重构代码(前台)
- 第十章:重构后台M层
- 第一节:数据访问DAO层
- 第二节:项目整体重构
- 第十一章:用户登陆(前后台)
- 第一节:制定规范
- 第二节:定制测试用例
- 第三节:后台输入测试代码(后台)
- 第四节:postman(后台)
- 第五节:新建用户登陆模块(前台)
- 第六节:代码重构(前台)
- 第十二章:班级管理(前后台)
- 第一节:班级列表
- 1 原型开发
- 2 制定规范
- 3 后台对接开发
- 4 前台对接开发
- 第二节:Add
- 1 原型开发
- 2 制定规范
- 3 后台对接开发
- 4 前台对接开发
- 第三节:Save
- 1 制定规范
- 2 后台对接开发
- 3 前台对接开发
- 第四节:Edit
- 1 原型开发
- 2 制定规范
- 3 后台对接开发
- 4 前台对接开发
- 第五节:Update
- 1 制定规范
- 2 后台对接开发
- 3 前台对接开发
- 第六节:Delete
- 1 制定规范
- 2 后台对接开发
- 3 前台对接开发
- 第七节:小结
- 第十三章:班级管理(API)
- 第一节:ER图
- 第二节:create
- 1 实体层
- 2 dao层
- 3 service(server)层
- 4 action层
- 第三节:ManyToOne
- 第四节:Read
- 1 service(server)层
- 2 action层
- 第五节:update
- 1 service(server)层
- 2 action层
- 第六节:update
- 第十四章:重构服务层