大家好,欢迎来到IT知识分享网。
在做手机app时需要接入一个比较完整的商城,自己写没时间的情况下,接入有赞商城,现在记录下来。
/ * 有赞基本配置 * @author dxt */ public class YouZanConfig { //app接入有赞的client_id和client_secret public static String client_id=""; public static String client_secret=""; public static String kdt_id=""; public static String loginUrl="https://uic.youzan.com/sso/open/login"; public static String loginoutUrl="https://uic.youzan.com/sso/open/logout"; public static String initTokenUrl="https://uic.youzan.com/sso/open/initToken"; public static String TokenUrl="https://open.youzan.com/oauth/token"; public static String tradesUrl="https://open.youzan.com/api/oauthentry/youzan.trades.sold/3.0.0/get"; }
需要一个可以发送网络请求的方法
public class MyX509TrustManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }
public class YouZanHttp { / * 发送https请求 * @param requestUrl 请求地址 * @param requestMethod 请求方式(GET、POST) * @param outputStr 提交的数据 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值) */ public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) { JSONObject jsonObject = null; try { // 创建SSLContext对象,并使用我们指定的信任管理器初始化 TrustManager[] tm = { new MyX509TrustManager() }; SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE"); sslContext.init(null, tm, new java.security.SecureRandom()); // 从上述SSLContext对象中得到SSLSocketFactory对象 SSLSocketFactory ssf = sslContext.getSocketFactory(); URL url = new URL(requestUrl); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//请求方式 // 设置请求方式(GET/POST) conn.setRequestMethod(requestMethod); // 当outputStr不为null时向输出流写数据 if (null != outputStr) { OutputStream outputStream = conn.getOutputStream(); // 注意编码格式 outputStream.write(outputStr.getBytes("UTF-8")); outputStream.close(); } // 从输入流读取返回内容 InputStream inputStream = conn.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = bufferedReader.readLine()) != null) { buffer.append(str); } // 释放资源 bufferedReader.close(); inputStreamReader.close(); inputStream.close(); inputStream = null; conn.disconnect(); jsonObject = new JSONObject(buffer.toString()); } catch (ConnectException ce) { System.out.println("连接超时:{}"); } catch (Exception e) { System.out.println("https请求异常:{}"); } return jsonObject; }
所有的网络都是post请求,
/ * 获取有赞返回的json登陆消息 * @param userid * @return */ public static JSONObject getYouzan(String userid){ JSONObject json=null; String content="client_id="+YouZanConfig.client_id+"&client_secret="+YouZanConfig.client_secret+"&open_user_id="+userid; json= YouZanHttp.httpsRequest(YouZanConfig.loginUrl, "POST", content); return json; }
如图是有赞的文档
https://www.youzanyun.com/docs/guide/appsdk/683?from_source=pzshouye&
在登陆过程中,需要有自己的独立账号体系作为app登陆有赞的账户系统,如果你是用在微信公众号中,则不需要有独立账号,只需要授权有赞接入到微信公众号,
如上初始化token的请求过程,下图是登陆过程,只需要传入自己的userid就可以登陆有赞商城
将上面的三个参数返回给app客户端,因为有赞的appsdk中做了缓存功能 ,上面说的token七天的有效期不需要后台来做处理,有赞的sdk在签证这几个参数失效后有自己的回调触发事件,客户端app只要根据代码实现事件回调逻辑就可以完成有赞在app中嵌入的过程。
原生安卓https://www.youzanyun.com/docs/guide/appsdk/688?from_source=pzshouye&
下面是根据接口获取有赞订单信息,放入自己的数据库,方便统计,用定时器做每天晚上获取一次,因为不是按照时间段获取,而是全部获取订单完成(签收状态),每次都是相同操作
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import com.ruchuapp.tools.DbUtil; import com.ruchuapp.tools.StringUtil; import com.youzan.open.sdk.client.auth.Token; import com.youzan.open.sdk.client.core.DefaultYZClient; import com.youzan.open.sdk.client.core.YZClient; import com.youzan.open.sdk.gen.v3_0_0.api.YouzanTradesSoldGet; import com.youzan.open.sdk.gen.v3_0_0.api.YouzanUserWeixinOpenidGet; import com.youzan.open.sdk.gen.v3_0_0.model.YouzanTradesSoldGetParams; import com.youzan.open.sdk.gen.v3_0_0.model.YouzanTradesSoldGetResult; import com.youzan.open.sdk.gen.v3_0_0.model.YouzanUserWeixinOpenidGetParams; import com.youzan.open.sdk.gen.v3_0_0.model.YouzanUserWeixinOpenidGetResult; / * 开启一个线程,用于在固定的时间段从有赞数据库获取订单记录 */ @WebServlet("/YouZanInitServlet") public class YouZanInitServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override public void init() throws ServletException { super.init(); Calendar cal=Calendar.getInstance(); cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); cal.set(Calendar.SECOND, 59); Timer time=new Timer(); time.schedule(new TimerTask() { @Override public void run() { //在这里做获取订单消息 JSONObject tradesInfo = getTradesInfo(); getMustMess(tradesInfo); } }, cal.getTimeInMillis(),24*60*60*1000); } / * 获取有赞商品订单 * 发起网络请求获取返回的订单信息 * @return */ private static JSONObject getTradesInfo(){ JSONObject json=null; //"8dd8ca0de6e631e396be624e659e7b5a" String accessToken = getAccessToken.getAccessToken(); YZClient client = new DefaultYZClient(new Token(accessToken)); //new Sign(appKey, appSecret) // YZClient client = new DefaultYZClient(new Token("18378bf25aa7305f8436ff9c37f15965")); //new Sign(appKey, appSecret) YouzanTradesSoldGetParams youzanTradesSoldGetParams = new YouzanTradesSoldGetParams(); // youzanTradesSoldGetParams.setPageNo(1L); youzanTradesSoldGetParams.setType("ALL"); youzanTradesSoldGetParams.setStatus("TRADE_BUYER_SIGNED");//只查找订单完成签收的订单列表 YouzanTradesSoldGet youzanTradesSoldGet = new YouzanTradesSoldGet(); youzanTradesSoldGet.setAPIParams(youzanTradesSoldGetParams); YouzanTradesSoldGetResult result = client.invoke(youzanTradesSoldGet); try { json=new JSONObject(result.toString()); } catch (Exception e) { e.printStackTrace(); } return json; } / * 通过手机号获取微信用户的openid * @param tel * @return */ private static String getUserOpenid(String tel){ String str=""; YZClient client = new DefaultYZClient(new Token("token")); //new Sign(appKey, appSecret) YouzanUserWeixinOpenidGetParams youzanUserWeixinOpenidGetParams = new YouzanUserWeixinOpenidGetParams(); youzanUserWeixinOpenidGetParams.setMobile(tel); youzanUserWeixinOpenidGetParams.setCountryCode("+86"); YouzanUserWeixinOpenidGet youzanUserWeixinOpenidGet = new YouzanUserWeixinOpenidGet(); youzanUserWeixinOpenidGet.setAPIParams(youzanUserWeixinOpenidGetParams); YouzanUserWeixinOpenidGetResult result = client.invoke(youzanUserWeixinOpenidGet); JSONObject json=new JSONObject(result); // json.getString(""); boolean has = json.has("response"); if(!has){//有的情况下 str=""; }else{ try { JSONObject jo= (JSONObject) json.get("response"); String opneid = jo.getString("open_id"); str=opneid; } catch (JSONException e) { e.printStackTrace(); } } return str; } / * 获取订单信息并进行比较,插入操作 * @param jo */ private void getMustMess(JSONObject jo){ try { JSONArray ja=new JSONArray(jo.get("trades").toString()); if(ja.length()==0){ return; } for(int i=0;i<ja.length();i++){ JSONObject json = (JSONObject) ja.get(i); String tid = json.getString("tid");//订单唯一标识 String title = json.getString("title");//订单标题 String outerUserId = json.getString("outerUserId");//订单用户id String payment = json.getString("payment");//订单实际收费金额 // String payType = json.getString("payType");//订单支付类型,如支付宝,微信支付 //因为在微信情况下,不能获取到微信用户的账户系统,所以现在获取手机号作为判断的一个条件 String receiverState = json.getString("receiverState");//订单中收货人的手机号 String sign_time = json.getString("sign_time");//订单签收的日期,钱到账的日期,获取的时间格式需要转一下 Date date = getDate(sign_time); //需要判断这个订单表是否在表中已经有了,如果有了就不要插入 if(outerUserId.equals("0")){//说明这个订单是从微信服务号来的 //根据手机号获取用户opneid String userOpenid = getUserOpenid(receiverState); if(StringUtil.isEmpty(userOpenid)){//为null表示这个订单不是从当前关注的公众号发出的,可能是分享给别人购买的订单 continue; //如果不是关注当前公众号的人购买的暂不做处理 }else{//确实是从微信公众号出来的订单 //通过openid换取u_id String userUid = getUserUid(userOpenid); boolean compareIsHandOrders = compareIsHandOrders(tid); if(compareIsHandOrders){//确实有这个订单id continue; }else{//没有这个订单id insertOrderInfo(userUid,"微信商城",tid,payment,title,date); } } }else{//订单从app里面来的有账号系统 boolean compareIsHandOrders = compareIsHandOrders(tid); if(compareIsHandOrders){//确实有这个订单id continue; }else{//没有这个订单id String uid = getUserTid(outerUserId); insertOrderInfo(uid,"app商城",tid,payment,title,date); } } } } catch (JSONException e) { e.printStackTrace(); } } //转换日期 private Date getDate(String time){ SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", java.util.Locale.US); Date date = null; try { date = sdf.parse(time); } catch (ParseException e) { e.printStackTrace(); } return new java.sql.Date(date.getTime()); } / *判断在订单表中是否含有这条订单信息,如果有就不进行插入操作,没有在插入 */ private static boolean compareIsHandOrders(String tid){ boolean flag=false; String sql="select order_id from usercost where order_id=?"; Connection conn=null; PreparedStatement ps=null; ResultSet rs=null; try { conn=DbUtil.getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, tid); rs=ps.executeQuery(); if(rs.next()){ flag=true; } } catch (SQLException e) { e.printStackTrace(); }finally{ DbUtil.closeResultSet(rs); DbUtil.closeStatement(ps); DbUtil.closeConnection(conn); } return flag; } / * 插入一条订单记录 * @return */ private static void insertOrderInfo(String usertid,String order_from,String oderidid,String mount,String costname,Date time){ String uid = getUserTid(usertid); String sql="insert into usercost(user_id,order_id,order_from,amount,cost_type,cost_name,uc_createtime)values(?,?,?,?,?,?,?)"; Connection conn=null; PreparedStatement ps=null; try { conn=DbUtil.getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, oderidid); ps.setString(3, order_from); ps.setString(4, mount); ps.setString(5, "2"); ps.setString(6, costname); ps.setDate(7, (java.sql.Date) time); ps.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally{ DbUtil.closeStatement(ps); DbUtil.closeConnection(conn); } } / * 获取user表中的u_id * @param tid * @return */ private static String getUserTid(String tid){ String sql="select u_id from user where user_id=?"; Connection conn=null; PreparedStatement ps=null; ResultSet rs=null; String usertid=""; try { conn=DbUtil.getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, tid); rs=ps.executeQuery(); if(rs.next()){ usertid=rs.getString("u_id"); } } catch (SQLException e) { e.printStackTrace(); }finally{ DbUtil.closeResultSet(rs); DbUtil.closeStatement(ps); DbUtil.closeConnection(conn); } return usertid; } / * 通过opneid获取到用户的u_id * @param opneid * @return */ private static String getUserUid(String opneid){ String sql="select u_id from user where u_openid=?"; Connection conn=null; PreparedStatement ps=null; ResultSet rs=null; String uid=""; try { conn=DbUtil.getConnection(); ps=conn.prepareStatement(sql); ps.setString(1, opneid); rs=ps.executeQuery(); if(rs.next()){ uid=rs.getString("u_id"); } } catch (SQLException e) { e.printStackTrace(); }finally{ DbUtil.closeResultSet(rs); DbUtil.closeStatement(ps); DbUtil.closeConnection(conn); } return uid; } }
因为有赞的token七天内都是有效的,就将这个tokn缓存下来,
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Calendar; import java.util.Timer; import java.util.TimerTask; import javax.servlet.Servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import org.json.JSONException; import org.json.JSONObject; import com.ruchuapp.tools.CreateOnlyID; import com.ruchuapp.tools.DbUtil; / * 开启一个线程,每七天获取有赞的token一次 */ @WebServlet("/InitYouzanTokenServlet") public class InitYouzanTokenServlet extends HttpServlet implements Servlet { private static final long serialVersionUID = 1L; @Override public void init() throws ServletException { super.init(); try { JSONObject youzan = getYouzan(); boolean insertAccessToken = insertAccessToken(youzan.getString("access_token"),youzan.getString("expires_in")); if(insertAccessToken){ System.out.println("youzan七天的token生成了哦"); }else{ System.out.println("youzan七天的token有问题呢"); } } catch (JSONException e1) { e1.printStackTrace(); } System.out.println(""); Calendar cal=Calendar.getInstance(); long timeInMillis = cal.getTimeInMillis(); Timer time=new Timer(); time.schedule(new TimerTask() { @Override public void run() { System.out.println("3"); try { JSONObject youzan = getYouzan(); boolean insertAccessToken = insertAccessToken(youzan.getString("access_token"),youzan.getString("expires_in")); if(insertAccessToken){ System.out.println("youzan七天的token生成了哦"); }else{ System.out.println("youzan七天的token有问题呢"); } } catch (Exception e) { e.printStackTrace(); } } }, timeInMillis, 7*24*60*60*1000); } / * 获取有赞返回的json登陆消息 * @param userid * @return */ public static JSONObject getYouzan(){ String content="client_id="+YouZanConfig.client_id+"&client_secret="+YouZanConfig.client_secret+"&grant_type=silent&kdt_id="+YouZanConfig.kdt_id; JSONObject json= YouZanHttp.httpsRequest(YouZanConfig.TokenUrl, "POST", content); return json; } / * 将获取到的token放到数据库中 * @param accesstoken * @param time * @return */ public boolean insertAccessToken(String accesstoken,String time){ boolean flag=false; String truncateSql = "truncate table app_youzan_accesstoken"; String sql = "insert into app_youzan_accesstoken(tid,access_token,expires_in,create_time,bz)values(?,?,?,now(),?)"; Connection conn=null; PreparedStatement pst1=null; PreparedStatement pst=null; int a=0; try{ conn = DbUtil.getConnection(); pst1 = conn.prepareStatement(truncateSql); pst = conn.prepareStatement(sql); String id = CreateOnlyID.getId(); // 获取当前时间插入数据库 pst.setString(1, id); pst.setString(2, accesstoken); pst.setString(3, time); pst.setString(4, ""); pst1.execute(); a= pst.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); }finally{ DbUtil.closeStatement(pst); DbUtil.closeStatement(pst1); DbUtil.closeConnection(conn); } if(a>0){ flag=true; } return flag; } }
登出逻辑个登入是一样的,在前端请求的时候调用接口就可以
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/155070.html