本文档由开发者左良(ONLYXX)撰写和维护,感谢其对帆软生态的贡献。[]~( ̄▽ ̄)~*
在这个例子中我们需要用到用户数据相关的操作类,
帆软提供了一个相当方便的工具类,可以实现快速的增删改查后台管理用户:
com.fr.fs.control.UserControl
以下是该类的源码及注释:
ok,有了上面这个类,要实现第三方登陆就很容易了。
第三方登陆通常需要一个接口来接收第三方登陆之后的回调,那么我们需要新增一个接口来创建一个actions
在plugin.xml中配置扩展一个webService
创建Service
这里创建的实际上是一个Service总线,这个插件所有用到的action都通过这个总线来转发
我们的actions需要继承Service接口
看看实现类:
Actions实现
展开源码
package com.fr.plugin;
import com.fr.plugin.actions.BlueMessageLoginAction;
import com.fr.plugin.actions.GetAction;
import com.fr.plugin.actions.SaveAction;
import com.fr.plugin.actions.UserTransferAction;
import com.fr.plugin.utilUrlUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.Service;
import com.fr.web.core.ActionNoSessionCMD;
import com.fr.web.core.WebActionsDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Actions implements Service {
// 该数组使用来存放将要用到的所有真正的服务方法的
private ActionNoSessionCMD[] actions = {
new LoginAction()
};
@Override
public String actionOP() {
//服务总线名称 调用的时候 op=my_plugin_actions
return "my_plugin_actions";
}
@Override
public void process(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, String s, String s1) throws Exception {
//转发对应的cmd到应用的实现类上
WebActionsDispatcher.dealForActionNoSessionIDCMD(httpServletRequest, httpServletResponse, actions);
}
}
在代码中有一个ActionNoSessionCMD 数组,这个数组的类需要实现ActionCMD,
我们看看loginAction的实现
登陆方法
package com.fr.plugin.actions;
import com.fr.base.TemplateUtils;
import com.fr.cluster.stable.ClusterState;
import com.fr.file.BaseClusterHelper;
import com.fr.file.ClusterConfigManager;
import com.fr.file.ClusterService;
import com.fr.fs.base.entity.User;
import com.fr.fs.base.entity.UserInfo;
import com.fr.fs.control.UserControl;
import com.fr.fs.web.FSConstants;
import com.fr.general.ComparatorUtils;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.plugin.pojo.BlueMessageUserInfo;
import com.fr.plugin.pojo.UserModel;
import com.fr.plugin.utilHttpUtils;
import com.fr.plugin.utilUrlUtils;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import com.fr.web.cluster.ClusterManager;
import com.fr.web.core.ActionNoSessionCMD;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class BlueMessageLoginAction extends ActionNoSessionCMD {
@Override
public String getCMD() {
return "blue_message_login";
}
@Override
public void actionCMD(HttpServletRequest req, HttpServletResponse httpServletResponse) throws Exception {
PrintWriter writer = WebUtils.createPrintWriter(httpServletResponse);
String code = req.getParameter("code");
if (StringUtils.isNotBlank(code)) {
BlueMessageUserInfo userInfo=null;
try {
userInfo = Service.getOauth2AccessToken(code);//通过转发过来的code获取第三方系统中的用户信息
}catch (Exception e){
writer.write("错误:"+e.getMessage());
writer.flush();
writer.close();
return;
}
if (userInfo != null) {
HttpSession session = req.getSession(true);
BlueMessageUserInfo newUser = Service.getUserInfo(userInfo);
UserModel userModel = newUser.getUserModel();
if (userModel != null) {
UserControl userControl = UserControl.getInstance();
User userByMobile = userControl.getUserByMobile(userModel.getMobile());//通过对方系统的手机号,或者其他关联的信息,查询出帆软的用户信息
if (userByMobile != null) {//用户存在则直接登陆成功,跳转到帆软主页
String password = userByMobile.getPassword();
String username = userByMobile.getUsername();
UserInfo ui = new UserInfo(username, password,true);
ui.dealBrowserCookies(httpServletResponse, session);
boolean isTemplate = ComparatorUtils.equals(true, session.getAttribute("isTemplate"));
Object oo = session.getAttribute(isTemplate ? Constants.PF.TEMPLATE_ORIGINAL_URL : Constants.ORIGINAL_URL);
String url = (oo == null) ? getRenderedUrl() : oo.toString()
+ "&_=" + System.currentTimeMillis();
addServerID(session);
httpServletResponse.sendRedirect(url);
return;
}else {//用户不存在则创建一个账户,并跳转到主页
User user=new User(userModel.getMobile(),"123456",userModel.getName());
user.setMobile(userModel.getMobile());
user.setEmail(userModel.getEmail());
user.setWorkphone(user.getMobile());
userControl.addUser(user);
UserInfo ui = new UserInfo(userModel.getId(),"123456",true);
ui.dealBrowserCookies(httpServletResponse, session);
boolean isTemplate = ComparatorUtils.equals(true, session.getAttribute("isTemplate"));
Object oo = session.getAttribute(isTemplate ? Constants.PF.TEMPLATE_ORIGINAL_URL : Constants.ORIGINAL_URL);
String url = (oo == null) ? getRenderedUrl() : oo.toString()
+ "&_=" + System.currentTimeMillis();
addServerID(session);
httpServletResponse.sendRedirect(url);
return;
}
}
}
}
writer.write("系统错误~");
writer.flush();
writer.close();
}
private void addServerID(HttpSession session) {
if (ClusterConfigManager.getInstance().isUseCluster()) {
ClusterService mainService = ClusterManager.getInstance().getMainService();
String serviceName = mainService.getServiceName() + "_" + System.currentTimeMillis();
session.setAttribute(FSConstants.SERVER_ID, serviceName);
}
}
// 获取主页路径
public static String getRenderedUrl() throws Exception {
Map para = new HashMap();
if (BaseClusterHelper.getClusterState() == ClusterState.LEADER) {
para.put("serverURL", "http://" + ClusterConfigManager.getInstance().getPublicURL());
}
return TemplateUtils.renderParameter4Tpl("${serverURL}${servletURL}?op=fs", para);
}
}
这个类有一个getCMD方法就是返回一个用来呗调用的接口前面我们定义的action总线,这里定义的是action后面的某一个方法,有点类似于spring里面的reqeustMapping一个是打在类上,一个是打在注解上,类上的相当于命名空间,方法上的相当于真实操作。
帆软这里的设定也是一样的。
在上面的代码中涉及到用户的查询和新增,他们都是使用UserControl userControl = UserControl.getInstance(); 来操作的,里面还有很多方法可以供大家使用
因为对接的第三方不同,可能实现上,有所不同,但是只要明白了,新增接口,操作用户的原理,那么就不困难了