WebService CXF3 范例-程序员宅基地

有几个原则:
1. 统一接口、统一方法、统一加密解密方式、统一WebService安全认证方式
新工程确认jar是否存在 sxnic-ws-xxx.jar(此包中包括接口、安全认证、WebService客户工具类)  sxnic-comm-3.0.0.jar(此包包括Base64加密解密工具类及Json工具类)

2.加密解密要求:客户端对三个参数都加密,服务端返回的json中只加密业务数据,对status和message不加密

接口如下,仅供参考,无需自己创建
[code="java"]
@WebService
public interface SxnicWebService {
/**
* 
* @param siteCode 子系统的编码
* @param func 调用方法名
* @param params
* @return
*/
public String execute(String siteCode,String func,String params);
}
[/code]

服务端配置
首先实现WebService接口,如下
[code="java"]
@WebService
@Service("UcenterNewWebServiceBean")
public class UcenterNewWebServiceImpl implements SxnicWebService {

    private static Logger logger = LoggerFactory.getLogger(UcenterNewWebServiceImpl.class);

    @Autowired
    private WebsiteManager siteManager;

    @Autowired
    private UserExtManager ueManager;

    @Autowired
    private UserManager userManager;

    private String msg;
    
    private String result;

    @Override
    public String execute(String siteCode, String func, String params) {
        logger.debug("===UcenterNewWebServiceImpl===execute start===");
        msg = "200";
        result = "";

        innoExecute(siteCode, func, params);

        if ("200".equals(msg)) {
            // 无需回传数据
            if (StringUtils.isBlank(result)) {
                logger.debug("===UcenterNewWebServiceImpl===处理成功,无需返回数据直接返回Json===");
                result = MsgUtils.crtSuccessMsg("json");
            } else {
                logger.debug("===UcenterNewWebServiceImpl===处理成功,需返回业务数据===");
                result = MsgUtils.crtSuccessMsg(Base64Utils.encode(result), "json");
            }
        } else {
            logger.warn("===UcenterNewWebServiceImpl===errorCode:{}===", msg);
            result = MsgUtils.crtErrorMsg(msg, "json");
        }

        logger.debug("===UcenterNewWebServiceImpl===execute end===status:" + msg);
        return result;
    }

    public void innoExecute(String siteCode, String func, String params) {
        try {
            if (StringUtils.isBlank(siteCode) || StringUtils.isBlank(func)) {
                msg = "450";
                return;
            }

            // 解密
            siteCode = Base64Utils.dccode(siteCode);
            func = Base64Utils.dccode(func);

            if (StringUtils.isNotBlank(params)) {
                params = Base64Utils.dccode(params);
                if (JsonUtils.isBadJson(params)) {
                    msg = "451";
                    return;
                }
            }

            logger.debug("===UcenterNewWebServiceImpl===参数={}={}={}", new String[] { siteCode, func, params });

            // 验证siteCode合法性
            if (!"dcenter".equals(siteCode) && !WsConstants.WEBSITE_MAP.containsKey(siteCode)) {
                msg = "452";
                return;
            }

            Gson gson = new Gson();

            // 判断func
            if ("getWebSite".equals(func)) {

                // params参数解析,如果没有参数表示查询所有的,如果有参数那么设定参数格式"code":"c1,c2,c3"
                // 具体方法调用
                if (StringUtils.isBlank(params)) {
                    result = UcenterWsUtils.WebsiteListtoJson(siteManager.findBy("enabled", true));
                } else {
                    String[] codes = StringUtils.split(StringUtils.substringBetween(params, ":\"", "\""), ",");
                    HibernateCriteria hc = new HibernateCriteria();
                    hc.add(Restrictions.in("code", codes));
                    result = UcenterWsUtils.WebsiteListtoJson(siteManager.getByCriteria(hc));
                }
            } else if ("getDept".equals(func)) {
                // 组织机构
                if (StringUtils.isBlank(params)) {
                    result = UcenterWsUtils.UserExttoJson(ueManager.findBy("userType", UserExt.USERTYPE_XZDW));
                }
            } else if ("login".equals(func)) {
                Map<String, String> map = gson.fromJson(params, Map.class);
                // 登陆授权
                String usn = map.get("usn");
                String pwd = map.get("pwd");
                // 判断参数是否有效
                if (StringUtils.isBlank(usn) || StringUtils.isBlank(pwd)) {
                    msg = "201";
                    return;
                }

                Subject subject = SecurityUtils.getSubject();
                UsernamePasswordToken token = new UsernamePasswordToken(usn, pwd, false);

                try {
                    subject.login(token);
                } catch (UnknownAccountException ex) {
                    msg = "210";
                    return;
                } catch (LockedAccountException lae) {
                    msg = "211";
                    return;
                } catch (AuthenticationException e) {
                    msg = "212";
                    return;
                } catch (Exception exp) {
                    msg = "212";
                    return;
                }

                String username = subject.getPrincipal().toString();
                User user = userManager.findByUnique("username", username);
                if (user != null) {
                    // 设置user的最后登录时间
                    user.setLastLoginDate(new Date());
                    user.setLastLoginClient("wsuc_" + siteCode);
                    userManager.save(user);
                }
                result = "{\"roles\":\"" + user.getStringRoles() + "\"}";
            } else if ("creUser".equals(func)) {
                // 创建用户
                Map<String, String> map = gson.fromJson(params, Map.class);
                // 登陆授权
                String username = map.get("username");
                String password = map.get("password");
                String email = map.get("email");

                if (StringUtils.isBlank(username) || StringUtils.isBlank(password) || StringUtils.isBlank(email)) {
                    msg = "201";
                    return;
                }

                User user = userManager.getUserByUsername((String) map.get("username"));
                if (user != null) {
                    msg = "218";
                    return;
                }
                user = userManager.getUserByEmail((String) map.get("email"));
                if (user != null) {
                    msg = "219";
                    return;
                }

                user = new User();
                user.setUsername((String) map.get("username"));
                user.setFullname((String) map.get("fullname"));
                user.setPassword((String) map.get("password"));
                user.setEmail((String) map.get("email"));
                // user.setIdcard((String)map.get("idcard"));
                user.setProblem((String) map.get("problem"));
                user.setAnswer((String) map.get("answer"));
                user.setWebsiteId(siteCode);
                user.setPassword(DigestUtils.md5Hex(user.getPassword()));// 对用户+密码加密
                user.setPriority(10);
                user.setUserOrder(1000);
                user.setEnabled(true);
                user.setCreationDate(new Date());
                try {
                    userManager.save(user);
                } catch (Exception e) {
                    msg = "220";
                    return;
                }

            } else {
                // func错误
                msg = "453";
                return;
            }
        } catch (DecodeException e) {
            msg = "450";
            return;
        } catch (Exception e) {
            msg = "500";
            return;
        }
    }

}

[/code]

spring-cxf配置文件
[code="java"]
<jaxws:endpoint id="nucenterSerivce" implementor="#UcenterNewWebServiceBean"
address="/nwsuc">
    <jaxws:inInterceptors>
      <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" />
      <ref bean="sxnicWsAuthHandler" />
    </jaxws:inInterceptors>
</jaxws:endpoint>

<bean id="sxnicWsAuthHandler" class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
  <constructor-arg>
    <map>
      <entry key="action" value="UsernameToken" />
      <entry key="passwordType" value="PasswordText" />
      <entry key="passwordCallbackRef">
       <ref bean="wsServerAuthHandler" />
      </entry>
    </map>
  </constructor-arg>
</bean>

[/code]

客户端
工具类WsClientUtils
包括两个常用的方式:getUcenterService获取用户中心Service 和 getDcenterService获取数据中心Service
注意上述两方法需要在属性表中有两个参数:ucenter.wsurl 和dcenter.wsurl
客户端Demo(带安全认证)
[code="java"]
/**
* 根据WebService的URL建立客户端
* 
* @param url
* @return
* @throws WebServiceException
*/
public static SxnicWebService getServiceByUrl(String url) throws WebServiceException {

try {
JaxWsProxyFactoryBean svr = new JaxWsProxyFactoryBean();
svr.setServiceClass(SxnicWebService.class);
svr.setAddress(url);

Map<String, Object> props = new HashMap<String, Object>();
props.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
// 这个WSHandlerConstants.USER 变量暂时不知道什么作用,但是必须有
props.put(WSHandlerConstants.USER, "sxnic");
props.put(WSHandlerConstants.PASSWORD_TYPE, "PasswordText");
props.put(WSHandlerConstants.PW_CALLBACK_CLASS, WsClientAuthHandler.class.getName());

WSS4JOutInterceptor oi = new WSS4JOutInterceptor(props);
svr.getOutInterceptors().add(new SAAJOutInterceptor());
svr.getOutInterceptors().add(oi);
return (SxnicWebService) svr.create();
} catch (Exception e) {
throw new WebServiceException("===WebService客户端构建异常!===");
}
}

[/code]

工具类:
[code="java"]
public class UcenterWsUtils {

    /**
     * 把WebSite子站点List转换为Json
     * @param list
     * @return
     */
    public static String WebsiteListtoJson(List<Website> list) {

        if (list == null || list.size() == 0) {
            return "{}";
        }

        StringBuffer sb = new StringBuffer();
        sb.append("[");

        for (Website ws : list) {
            sb.append("{");
            sb.append("\"code\":\"" + ws.getCode() + "\",");
            sb.append("\"name\":\"" + ws.getName() + "\",");
            sb.append("\"str1\":\"" + (StringUtils.isBlank(ws.getTokenCode()) ? "token" : ws.getTokenCode()) + "\",");
            sb.append("\"str2\":\"" + (StringUtils.isBlank(ws.getUrl()) ? "url" : ws.getUrl()) + "\",");
            sb.append("\"str3\":\"" + (StringUtils.isBlank(ws.getWsurl()) ? "wsurl" : ws.getWsurl()) + "\"},");
        }

        return StringUtils.removeEnd(sb.toString(), ",") + "]";
    }

    /**
     * 把服务器返回来的Json中data部分,转化为map,适用于data部分加密的情况下
     * @param json
     * @return
     */
    public static Map<String, WrapperBean> JsonDatatoWebsiteMap(String json) {
        if (JsonUtils.isBadJson(json)) {
            return null;
        }

        Gson gson = new Gson();
        Map<String, WrapperBean> map = new HashMap<String, WrapperBean>();
        List<WrapperBean> list = gson.fromJson(json, new TypeToken<List<WrapperBean>>() {
        }.getType());

        for (WrapperBean b : list) {
            map.put(b.getCode(), b);
        }

        return map;
    }

    /**
     *  把服务器返回来的Json,转化为map,json不加密的情况下
     * @param json
     * @return
     */
    public static Map<String, WrapperBean> JsontoWebsiteMap(String json) {
        Map<String, WrapperBean> map = new HashMap<String, WrapperBean>();

        if (JsonUtils.isBadJson(json)) {
            return null;
        }

        Gson gson = new Gson();
        Map<String, Object> map1 = gson.fromJson(json, Map.class);
        List<Map> listmap = (List<Map>) map1.get("data");
        for (Map u : listmap) {
            WrapperBean b = gson.fromJson(u.toString(), WrapperBean.class);
            map.put(b.getCode(), b);
        }

        return map;
    }

}
[/code]

WebService实现类的单元测试
[code="java"]
public class UcenterNewWsImplTest extends CommSpringJunitTest {

    @Autowired
    private SxnicWebService service;

    @Autowired
    private BaseCodeManager bcManager;

    @Autowired
    private PropertyManager ptManager;
    
    @Autowired
    private WebsiteManager siteManager;

    String token = "";
    String func = "";
    String params = "";

    @Test
    public void testGetWebSite() {
        bcManager.initNoYear();
        CommConstant.PROPERTY_MAP = ptManager.init();
        
        //清空数据
        siteManager.clear();
        
        //准备数据
        Website w = new Website();
        w.setCode("ucenter");
        w.setName("用户中心");
        w.setWsurl("wsurl");
        w.setUrl("url");
        w.setTokenCode("tokenCode-ucenter");
        
        siteManager.save(w);
        
        w = new Website();
        w.setCode("shenbao");
        w.setName("申报系统");
        w.setWsurl("wsurl");
        w.setUrl("url");
        w.setTokenCode("tokenCode-shenbao");
        
        siteManager.save(w);
        
        token = Base64Utils.encode("dcenter");
        func = Base64Utils.encode("getWebSite");
        params = "";

        //方法调用
        String result = service.execute(token, func, params);

        //结果解析
        Gson gson = new Gson();
        Map<String, Object> map = gson.fromJson(result, Map.class);

        //结果验证
        Assert.assertEquals("200", map.get("status"));

        String data = Base64Utils.dccode(String.valueOf(map.get("data")));

        List<WrapperBean> list = gson.fromJson(data, new TypeToken<List<WrapperBean>>() {
        }.getType());
        
        Assert.assertEquals(2, list.size());
        Assert.assertEquals("ucenter", list.get(0).getCode());
        
        Map<String, WrapperBean> map1 = UcenterWsUtils.JsonDatatoWebsiteMap(data);
        
        Assert.assertEquals(2, map1.size());
        Assert.assertTrue(map1.containsKey("shenbao"));
        Assert.assertEquals("用户中心", map1.get("ucenter").getName());
    }

}
[/code]

转载于:https://my.oschina.net/wowlinda/blog/550800

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chuosongjiang6936/article/details/101061878

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文