多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
经过前面的努力,我们已经有前后对接的条件。 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/), 打开控制台,并注意网络选项卡,如果数据成功返回的话,相信你已经能看到数据表中的数据了。