作者碎碎念:在前后端分离的项目中使用Session会不会有悖分离原则呢?
编写UserAction
在前文中我们已经能使用hibernate对数据库进行CRUD操作了,那么在这里我们将进行数据的请求。前后端分离的情况下进行数据传输的对象一般为Json数据,而在Struts2中的struts2-json-plugin-2.3.16.jar已经为我们提供了良好的json数据转换插件。因此我们可以快速的进行开发。
- 在action包中新建普通的java类
- 实现Action接口(com.opensymphony.xwork2.Action)
我们在红线地方按alt+enter键显示提示,实现Action的方法
这样IDE会为我们创建重写的execute方法,这个是在struts.xml文件中配置action不指定method方法时默认调用的方法,这里我们一般不去修改它。我们自定义login方法。但是自定义的方法也要遵循一定的规则。也就是返回类型必须为String。
由于我们要返回json数据类型,我们要创建一个Map(键值对)对象、并且还要接收前台传递过来的参数。
因此我们还要创建以下成员变量,当然我们不能忘了生成这些变量的set和get方法,否则struts2容器并不能为我们获取到前端传递过来的值。
private Map<String,Object> data=new HashMap<>();
private UserService userService = new UserService();
//前端传递过来的参数
private String username;
private int sid;
private int rid;
从上面的代码中我们看到使用了UserService类,其实这个是定义在service包中的类,用于操作dao层对象。
主要实现了登录注册,和查询聊天记录的方法。
详细代码如下:
package cn.zipple.service;
import cn.zipple.dao.impl.UserDaoImpl;
import cn.zipple.entity.ChatRecord;
import cn.zipple.entity.User;
import cn.zipple.util.Constant;
import cn.zipple.util.Log;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by zipple on 2017/11/13.
* 与用户相关的操作
*/
public class UserService {
private UserDaoImpl userDao =new UserDaoImpl();
/**
* 登录--注册
* @param username 用户名
* @return 返回登录对象
*/
public User login(String username) {
User user = userDao.getUserByUsername(username);//根据题目要求不验证密码-_-||
if (user==null){
user = register(username);
}
user.setLoginTime(new Timestamp(System.currentTimeMillis()));
userDao.upd(user);
return user;
}
/**
* 默认的注册方法
* @param username 用户名
* @return 返回操作是否成功
*/
private User register(String username){
User user = new User(username,"resource/images/avatar/default.png", Constant.MALE);//默认男性
userDao.save(user);
if (user.getId()>0){
Log.info("用户注册id:"+user.getId()+"成功");
}
return user;
}
/**
* 获取聊天记录
* @return 返回map
*/
public Map<Integer,Object> getChatRecords(int sendId,int receiveId){
List<ChatRecord> chatList = userDao.getAllObject("ChatRecord c"," order by c.time");
Map<Integer,Object> result = new HashMap<>();
int i=-1;//从零开始
for (ChatRecord cr: chatList) {
if (isHisChatRecords(cr,sendId,receiveId)){
Log.info(cr.getContent()+" "+cr.getTime());
result.put(++i,cr);
}
}
return result;
}
private boolean isHisChatRecords(ChatRecord cr,int sid,int rid){
if (cr.getReceiver()==rid&&cr.getSender().getId()==sid){
return true;
}
if (cr.getReceiver()==sid&&cr.getSender().getId()==rid){
return true;
}
return false;
}
public UserDaoImpl getUserDao() {
return userDao;
}
public void setUserDao(UserDaoImpl userDao) {
this.userDao = userDao;
}
}
- login方法
/**
* 登录操作
* @return 返回json
*/
public String login(){
User user;
if ((user = userService.login(username))!=null){
data.put("code",200);
data.put("info","登录/注册成功");
data.put("data",user);
// ActionContext.getContext().getSession()
ServletActionContext.getRequest().getSession().setAttribute("user",user);
Log.info("通过UserAction的login方法,储存session...");
}else{
data.put("code",500);
data.put("info","登录/注册失败,用户名:"+username);
data.put("data",null);
Log.info("未通过UserAction的login方法");
}
return SUCCESS;
}
注意:用户登录成功时需要将当前User对象保存至session中,以便于websocket程序在获取httpsession时一并获取到User实例
这样简单的登录接口就实现了。
接下来在struts.xml中配置这个action。
在这之前呢,我们还要对struts2进行补充配置,不然在编写struts.xml时没有struts的包提示…
还是打开project-structure
选中web,点击左上角的+号,选择struts2
选中所有的如图所示的三个xml
然后在struts.xml中这样配置action即可返回json数据
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="json" extends="struts-default,json-default" namespace="/user"><!--namespace名空间,就是给url加上前缀,这里表示要访问到这里的action中的login时要输入/user/login -->
<action name="login" class="cn.zipple.action.UserAction" method="login">
<result name="success" type="json">
<param name="root">data</param><!--action中定义的map对象-->
</result>
</action>
</package>
</struts>
运行测试,在火狐中输入localhost:8080/user/login?username=test,结果如下图所示:(使用火狐的原因是火狐能美化输出json数据…)