💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
在前面的小节中,我们已经成功的将前台交给了yoman来处理。前后台的完全分离,意味着,我们可以在一台服务器上布署前台代码,然后在另一台服务器上布署后台代码。也就是说,即使我们将前台与后台布署在了同一台服务器上,实际上前台和后台也是两套不同的系统。不同的系统间通讯较同一系统间的通信显得复杂一些。 前台与后台大体是这样通讯的: 1. 前台 通过http协议,发送一个请求(GET\POST)。 2. 后台 接收到这个请求后,返回json数据。 3. 前台 接到json数据后,为用户做出响应。 由于浏览器与后台交互 ,本质上也是在进行get,post请求。所以javaee在接收数据时没有什么不同。那么不同点就在于:以前我们返回的html数据,而此时,我们需要返回json格式的数据。 下面,我们设置我们的后台,使其能够返回前台可用的JSON数据。 # 去除后台冗余的代码 我们在上一章中,在前台建立了性别过滤器,所以后台teacher实体中的getSexAttr()方法已经成为了冗余方法。实际在前后台分离的开发中,我们也的确不会在后台的实体中增加一些类似于getXXXXAttr()的方法来进行转换运算。当然,在本教程中,如果我们不删除getSexAttr()方法,还会引发一些json转换错误。 `getSexAttr()`方法位于 `package com.mengyunzhi.javaee.entity.teacher`中 # 引入JSON Plugin struts如果返回json格式的数据呢?还记得我们一直强调的: > 做为初学者的我们,我们的需求早早的就被大牛们解决了。 没错,struts返回json也是如此. 我们仍然打开,struts2.5的docs文档文件夹,并在此启用一个http-server服务,然后在本地来快速查看struts的文档。 > 我们可以使用:`http-server -p 端口号` 来自行指定一个端口来避免冲突。 ![https://box.kancloud.cn/ce44b9c78141f512ae5896eb08b0b78b_1630x378.png](https://box.kancloud.cn/ce44b9c78141f512ae5896eb08b0b78b_1630x378.png) 我们依次打开:struts2-plugins/ -> struts2-json-plugin/ -> apidocs/ 最终打开struts2-plugins官方文档: [http://127.0.0.1:8081/struts2-plugins/struts2-json-plugin/apidocs/](http://127.0.0.1:8081/struts2-plugins/struts2-json-plugin/apidocs/) 然后找到左侧菜单,找到: ![https://box.kancloud.cn/886d6dbfbf77daccf82d5642a20f23a1_684x830.png](https://box.kancloud.cn/886d6dbfbf77daccf82d5642a20f23a1_684x830.png) 有前期,我们有教程的情况下,其实我们并不需要把官方文档读一遍。 但读官方文档绝对是学习一门新语言最正确的途径。我们要尝试着去读官方的说明文档,在前期结合google的情况下,能够弄清楚怎么使用官方文档。官方文档中的一些示例代码又是该如何应用到具体项目中的。 ## 复制jar包 我们在下载的struts中的lib文件夹中,找到struts2-json-plugin-2.3.31 ![https://box.kancloud.cn/441ef1e1b3075e699b963157128c0b05_1620x670.png](https://box.kancloud.cn/441ef1e1b3075e699b963157128c0b05_1620x670.png) 并复制到javaee项目中的WebContent下的WEB-INF下的lib文件夹中。 ## 添加Libraries 然后,我们在javaee上右键 -> build path -> Configure Build Path -> add JARS 然后找到我们刚刚复制过来的struts2-json-plugin-2.3.31, 应用并添加. ## 配置struts.xml 1. 修改包继承 ``` ... <!-- 继承自json-default. json-default是json插件为我们提供的 --> <package name="teacher" namespace="/teacher" extends="json-default"> ... ``` 2. 修改action返回类型及设置拦截器 ```http://localhost:8080/javaee/teacher/ ... <!-- 列表 --> <action name="index" class="com.mengyunzhi.javaee.action.teacher.Index"> <!-- 返回类型设置为json --> <result name="success" type="json"> </result> <!-- 配置拦截器,使传入的json数据能够成功的通过setXXX()方法来传值 --> <interceptor-ref name="defaultStack" /> <interceptor-ref name="json"> <param name="enableSMD">true</param> </interceptor-ref> </action> ... ``` 3. 重启tomcat 修改struts后,如果控制台没有重新启到tomcat的话,需要我们手动停止,然后再启动. ![https://box.kancloud.cn/72a945d05f7cdc07bdfa1bc42e99c40c_1882x190.png](https://box.kancloud.cn/72a945d05f7cdc07bdfa1bc42e99c40c_1882x190.png) ## 测试 此时,我们打开浏览器,并打开浏览器控制台。打开:[http://localhost:8080/javaee/teacher/](http://localhost:8080/javaee/teacher/) 查看返回信息: ![https://box.kancloud.cn/c3f5967672b6017b8b5c9c69876c7401_1020x344.png](https://box.kancloud.cn/c3f5967672b6017b8b5c9c69876c7401_1020x344.png) 返回值的类型为`application/json`,当浏览器接收到此信息时,会将接收到的数据做为json数据来处理。的确,当我们再查看JSON选项卡时,数据已经以json的形式展现给了我们。 我们再修改一下每页显示条数,然后查看数据返回是否正确。 [http://localhost:8080/javaee/teacher/?pageSize=3](http://localhost:8080/javaee/teacher/?pageSize=3) ![https://box.kancloud.cn/509326c302846a8f8bd0a8a6d7dbbd77_1678x402.png](https://box.kancloud.cn/509326c302846a8f8bd0a8a6d7dbbd77_1678x402.png) 数据返回3条数据,正确. <hr /> ### 删除后实体代码如下: ``` package com.mengyunzhi.javaee.entity; import java.util.ArrayList; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.Index; import com.mengyunzhi.javaee.common.db.MysqlJavaee; // 声明主体 @Entity public class Teacher { // 声明主键 // 声明一个名为idGenerator的native类型构造器 // 使用这个构造器设置ID为自增属性 @Id @GenericGenerator(name = "idGenerator", strategy = "native") @GeneratedValue(generator = "idGenerator") private int id; // 主键 private String name; // 姓名 // 声明长度(用户名不超过20位长度,定长能够提升效率) @Column(columnDefinition = "char(20)") // 声明为索引(该字段将来用于查询 ,增加索引将大幅提升查询效率) @Index(name = "username") private String username; // 用户名 private String email; // 邮箱 private Boolean sex = false; // 性别 0:男;1:女 // 密码采用sha1 md5加密,长度固定。 @Column(columnDefinition = "char(40)") private String password; // 密码 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Boolean getSex() { return sex; } public void setSex(Boolean sex) { this.sex = sex; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Teacher() { } public Teacher(int id, String name, String username, String email, Boolean sex, String password) { // super(); this.id = id; this.name = name; this.username = username; this.email = email; this.sex = sex; this.password = password; } public String toString() { return "Teacher [id=" + id + ", name=" + name + ", username=" + username + ", email=" + email + ", sex=" + sex + ", password=" + password + "]"; } @SuppressWarnings("unchecked") static public List<Teacher> all() { // 实例化列表 teachers List<Teacher> teachers = new ArrayList<Teacher>(); // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 查询Teacher表,注意:是Teacher ,而不是 teacher Query query = session.createQuery("from Teacher"); // 预查询,只有在事务提交时,才进行查询操作 teachers = query.list(); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return teachers; } /** * 分页数据 * * @param page * 第几页 * @param pageSize * 每页大小 * @return */ @SuppressWarnings("unchecked") static public List<Teacher> paginate(int page, int pageSize) { // 实例化列表 teachers List<Teacher> teachers = new ArrayList<Teacher>(); // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 查询Teacher表,注意:是Teacher ,而不是 teacher Query query = session.createQuery("from Teacher"); // 计算并设置第一条记录的位置 int index = (page - 1) * pageSize; query.setFirstResult(index); // 每页大小 query.setMaxResults(pageSize); teachers = query.list(); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return teachers; } /** * 分页数据 * * @param page * 第几页 * @param pageSize * 每页大小 * @return */ @SuppressWarnings("unchecked") static public List<Teacher> paginate(String name, int page, int pageSize) { // 实例化列表 teachers List<Teacher> teachers = new ArrayList<Teacher>(); // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 查询Teacher表,注意:是Teacher ,而不是 teacher Query query = session.createQuery("from Teacher where name like '%" + name + "%'"); // 计算并设置第一条记录的位置 int index = (page - 1) * pageSize; query.setFirstResult(index); // 每页大小 query.setMaxResults(pageSize); teachers = query.list(); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return teachers; } /** * 通过ID获取Teacher实体 * * @param id * @return */ static public Teacher getTeacherById(int id) { // 实例化Teacher Teacher teacher = new Teacher(); // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 使用Teacher.class来获取到Teacher的类名(包括包名) teacher = (Teacher) session.get(Teacher.class, id); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return teacher; } public Boolean update() { // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 更新 session.update(this); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return true; } public Boolean delete() { // 创建会话(这里的session也是会话的意思,我们以前接触的http中的session,处理的是用户与服务器的对话) Session session = MysqlJavaee.getCurrentSession(); // 开启事务(使用缓冲池进行数据库的连接) Transaction transaction = session.beginTransaction(); // 在这里,必须使用try catch finally语句。来确定会话正常关闭. // 否则,当操作数据库产生错误时,你可能需要重启mysql服务 try { // 删除 session.delete(this); // 提交事务 transaction.commit(); // 捕获异常 } catch (HibernateException e) { // 如果事务执行异常,则回滚事务 if (null != transaction) { transaction.rollback(); } // 打印异常 e.printStackTrace(); } finally { // 如果session处于开启状态,则关闭session if (session.isOpen()) { // 关闭会话 session.close(); } } return true; } } ``` 当习惯了完美的前端自动化开发后,我们好像已经不愿意在去手工去写那么冗余的代码了。