草庐IT

对接第三方顺丰丰桥下单Api接口实战教程java

小甘说码 2023-04-11 原文

对接第三方顺丰丰桥下单接口实战

前言

在接入第三方顺丰Api之前要先登录LaaS开放平台,如果您是首次与顺丰合作,可通过注册平台账号后登录。
如果您已有开放平台账号,可直接使用账号密码登录。如果您已有月结管家/速打平台/数据灯塔账号,可选择对应登录方式直接登录。如果您是顺丰内部员工,可选择顺丰工号登录方式完成域账号登录。
登录完成后需要进行个人认证或企业认证,如何进行认证小伙伴在顺丰控制台首页认证,认证完成后,需要审核月结卡号哦,如果已经有月结卡号就自行绑定即可,把这些相关信息都完成了,就可以对接顺丰接口啦,话不多说,接下来直接上代码。如果不还有不了解的可以给博主留言哦

pom文件顺丰依赖

pom文件引入顺丰sdk依赖,如何引入外部依赖到内部maven仓库之前的文件有教程,不懂如何引入外部依赖的可以去看我其他文章

Controller层

/**
	 * 生成顺丰丰桥快递订单
	 * @param keys
	 * @return
	 */
	@PostMapping("createSfOrder")
	public Result<FhhzdH> createSfOrder (@RequestBody List<Long> keys) throws UnsupportedEncodingException {
		return service.createSfOrder(keys);
	}

Service层

/**
	 * 生成顺丰丰桥快递订单
	 * @param keys
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	Result<FhhzdH> createSfOrder (List<Long> keys) throws UnsupportedEncodingException;

ServiceImpl实现类层

	/**
	 * 生成订单
	 */
	@SuppressWarnings("static-access")
	@Override
	@Transactional
	public Result<FhhzdH> createSfOrder(List<Long> keys) throws UnsupportedEncodingException {
		if (keys == null || keys.size() == 0) {
			return new Result<FhhzdH>().setCode(BussErrorCode.ARGUMENT_NOT_VALID).setReason("请求参数不能为空!");
		}
		for (int i = 0; i < keys.size(); i++) {
			Long key = keys.get(i);
			FhhzdH fhhzdH = mapper.selectByPrimaryKey(key);
			if (Common.isNull(fhhzdH)) {
				return new Result<FhhzdH>().setCode(BussErrorCode.ARGUMENT_NOT_VALID)
						.setReason("单号为" + key + "发货汇总单数据不存在!");
			}
			
			if (Common.isNotEmpty(fhhzdH.getKddh())) {
				throw new RuntimeException(
						String.format("单据号为[%s],快递单号为[%s]已发货", fhhzdH.getDjh(), fhhzdH.getKddh()));
			}
			//读取顺丰配置文件
			loadSfProperties();
			// 获取发货人信息
			FhrywhH fhrywhH = Common.requiredFirst(fhrywhHMapper.select(new RmFhrywhHQuery().letBm(fhhzdH.getFhr())),
					String.format("该%s编码发货人员配置不存在!", fhhzdH.getFhr()));	
			// 封装下单信息
			String msgData = orderInfo(fhhzdH, fhrywhH, SF_CARD_NO);
			CallExpressServiceTools tools = CallExpressServiceTools.getInstance();
			Map<String, String> params = new HashMap<String, String>();
			String timeStamp = String.valueOf(System.currentTimeMillis());
//	        String msgData =tools.packageMsgData(standardService);
			params.put("partnerID", CLIENT_CODE); // 顾客编码 ,对应丰桥上获取的clientCode
			params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
			params.put("serviceCode", EXP_RECE_CREATE_ORDER);// 接口服务码
			params.put("timestamp", timeStamp);
			params.put("msgData", msgData);
			params.put("msgDigest", tools.getMsgDigest(msgData, timeStamp, CHECK_WORD));
			String result = HttpClientUtil.post(CALL_URL_BOX, params);
			ShunFengResponse res = new Gson().fromJson(result, ShunFengResponse.class);
			String apiResultData = res.getApiResultData();
			ResultData data = new Gson().fromJson(apiResultData, ResultData.class);
			if (data.getSuccess() == true) {// 成功
				String sfdh = data.getMsgData().getWaybillNoInfoList().get(0).getWaybillNo();// 顺丰单号
				FhhzdH temp = new FhhzdH();
				temp.setDjlsh(key);
				temp.setKddh(sfdh);//顺丰下单返回的顺丰单号更新到自己的数据库,方便后续查询订单
				mapper.updateByPrimaryKeySelective(temp);
			} else {
				throw new RuntimeException(String.format("单据号为[%s],[%s]", fhhzdH.getDjh(), data.getErrorMsg()));
			}
		}
		return new Result<FhhzdH>().setCode(BussErrorCode.SUCCESS).setReason("顺丰下单成功!");
	}

封装请求参数

我自己是使用json格式,也可以使用xml格式,这个可以根据实际情况使用即可,请求参数不需要都要和我的一样,可根据实际开发需要去定义,这只是一个范例,有不了解的小伙伴可留言

**
	 * 顺丰丰桥下单请求参数
	 * @param fhhzdH
	 * @param fhrywhH
	 * @param sfCardNo
	 * @return
	 */
	private String orderInfo(FhhzdH fhhzdH, FhrywhH fhrywhH,String sfCardNo) {
		SfOrderParam param = new SfOrderParam();
		List<CargoDetail> cargoList = new ArrayList<CargoDetail>();
		CargoDetail cargo = new CargoDetail();//拖寄物信息
		cargo.setName("工艺品");//货物名称,如果需要生成电子运 单,则为必填。
		cargo.setCount(1L);//货物数量 跨境件报关需要填写
		cargo.setUnit("件");//货物单位,如:个、台、本,跨境 件报关需要填写。
		cargoList.add(cargo);	
		param.setCargoDetails(cargoList);//拖寄物信息	
		List<ContactInfo> contactInfoList = new ArrayList<ContactInfo>();
		ContactInfo info = new ContactInfo();
		// 获取发货方 省份,城市,县
		Map<String, String> map = addressResolution(fhrywhH.getJfdz());
		info.setContactType(1L);//地址类型: 1,寄件方信息 2,到件方信息
		info.setAddress(fhrywhH.getJfdz());//详细地址
		info.setCity(map.get("city"));
		info.setCompany(fhrywhH.getGsmc());
		info.setContact(fhrywhH.getJjr());// 联系人
		info.setCounty(map.get("county"));//所在县/区级行政区名称
		info.setMobile(fhrywhH.getJfdh());//寄方电话
		info.setProvince(map.get("province"));//所在省级行政区名称	
		contactInfoList.add(info);
		map.clear();
		// 获取收货方 省份,城市,县
		map = addressResolution(fhhzdH.getShdz());
		ContactInfo contactInfo = new ContactInfo();
		contactInfo.setContactType(2L);//地址类型: 1,寄件方信息 2,到件方信息
		contactInfo.setAddress(fhhzdH.getShdz());//详细地址收货地址
		contactInfo.setCity(map.get("city"));
		contactInfo.setCompany(fhhzdH.getMdmc());
		contactInfo.setContact(fhhzdH.getShouhr());// 收货人
		contactInfo.setCounty(map.get("county"));//所在县/区级行政区名称
		contactInfo.setMobile(fhhzdH.getLxdh());//收 联系电话
		contactInfo.setProvince(map.get("province"));//所在省级行政区名称
		contactInfoList.add(contactInfo);	
		param.setContactInfoList(contactInfoList);//收寄双方信息	
		param.setExpressTypeId(2L);
		param.setIsOneselfPickup(0L);//快件自取,支持以下值: 1:客户同意快件自取 0:客户不同意快件自取
		param.setLanguage("zh-CN");//语言
		param.setOrderId(fhhzdH.getDjh());//客户订单号
		param.setParcelQty(1L);//包裹数
		if ("1".equals(fhhzdH.getSfby())) {//付款方式,支持以下值: 1:寄方付 2:收方付 3:第三方付
			param.setPayMethod(1L); //包邮寄方付
		}else {
			param.setPayMethod(2L); //不包邮收方付
		}		
		param.setMonthlyCard(sfCardNo);//月结卡号
		param.setRemark(fhhzdH.getBz());	
		String msgData = new Gson().toJson(param).toString(); //把请求参数转成json格式
		log.info("顺丰丰桥下单请求参数:{}", msgData);
		return msgData;
	}

下单请求参数json参数示例

顺丰丰桥下单响应参数

拿到响应参数需要自己处理,因为顺丰返回的是json对象需要自己处理成自己需要的数据,就不一一演示了

以上代码看起来很多很复杂,其实是很简单的,实际还可以优化,如果对您有帮助劳烦帮忙点个赞,收藏关注一下,可以相互学习共同进步。

有关对接第三方顺丰丰桥下单Api接口实战教程java的更多相关文章

  1. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  2. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  3. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  4. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  5. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  6. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  7. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  8. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  9. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  10. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

随机推荐