睿乐购电商课程设计——总结

项目文件目录说明

  • html文件都在 src/main/resources/static目录下
  • 后台管理系统的文件位于src/main/resources/static/admin下
  • 前端编写放置在 src/main/resources/static/admin/rlg下
  • 接口编写再 src/main/java编写
    • annotation:自定义注解
    • config: 配置文件
    • controller: 控制层,接口处理
    • exception: 自定义异常类
    • mapper: 模型层,往数据库查询数据
    • popj: 数据库表对应的实体类
    • service: 业务层接口
      • impl: 接口实现类
    • util: 工具类
    • handler: 处理器
    • ShopApplication: 启动器
  • es.sql : 项目的数据库
    • 管理员账户密码:admin ysuadmin

命名说明与注意事项

  • 采用REST风格

    • get: 获取数据
    • post: 添加数据
    • delete: 删除数据
    • put: 修改数据
  • 操作命名

    • getUserById: 表示通过id获取用户
    • getUserList: 表示获取用户列表
    • addUser : 表示添加用户
    • delUser : 表示删除用户
    • updUser : 表示修改用户
    • By: 表示通过某些字段进行某些操作
    • Num|Count: 表示获取数据的大小
  • controller说明

    • 对于add操作,表里有的默认字段前端可以不传,mapper必须写,添加前需要校验,为空添加默认字段
  • 在对于测试的时候:使用日志输出

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private Logger log = LoggerFactory.getLogger(UserController.class);
log.debug("输出字段信息")

ajax参考

function login() {
    var userName = $("#username").val();
    var password = $("#password").val();
    if (isNull(userName)) {
        alert("请输入用户名!");
        return;
    }
    if (!validUserName(userName)) {
        alert("请输入正确的用户名!");
        return;
    }
    if (isNull(password)) {
        alert("请输入密码!");
        return;
    }
    if (!validPassword(password)) {
        alert("请输入正确的密码!");
        return;
    }
    var data = { "username": userName, "password": password }
    //console.log(data);
    $.ajax({
        type: "POST", //方法类型
        dataType: "json", //预期服务器返回的数据类型
        url: "http://localhost:8082/user/login",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(data),
        success: function(result) {
            console.log(result);
            if (result.status == 200) {
                setCookie("token", result.data.userToken);
                setCookie("username",username);
                window.location.href = "index.html";
            };
            if (result.status == 406 ) {
                alert("登陆失败!请检查账号和密码!");
                return;
            }
        },
        error: function() {
            alert("接口异常,请联系管理员!");
            return;
        }
    });
}

问题记录

jquery 获取表单数据

  • jquery 获取 获取select标签值
    • 元素内容 $('#searchId').find('option:selected').text()
    • 根据name $("select[name='searchId'] option:selected").val();
    • 根据id $("#searchId option:selected").val()
    • 设置value为pxx的项选中 $("#searchId").val("pxx");
    • 设置text为pxx的项选中 $("#searchId").find("option:contains('pxx')").attr("selected",true);

前后端分离方案

session与cookie
  • Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能。
  • Cookie的Domain和Path属性标识了这个Cookie是哪一个网站发送给浏览器的;Cookie的Expires属性标识了Cookie的有 效时间,当Cookie的有效时间过了之后,这些数据就被自动删除了。
  • Session是存放在服务器端的类似于HashTable结构(每一种Web开发技术的实现可能不一样,下文直接称之为HashTable)来存放用户 数据,当浏览器第一次发送请求时,服务器自动生成了一个HashTable和一个Session ID用来唯一标识这个HashTable,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应的HashTable。
token
  • 首次登录时,后端服务器判断用户账号密码正确之后,根据用户id、用户名、定义好的秘钥、过期时间 生成 token ,返回给前端

  • 前端拿到后端返回的 token ,存储在 localStroage 里

    • 赋值:localStorage.setItem("token", result.data.token); | localStorage.token= | localStorage[token]=
    • 读取信息:localStorage.getItem("token") | localStorage.token | localStorage[token]
    • 删除localStorage指定键对应的值:localStorage.removeItem('token');
    • 删除localStorage所有值: localStorage.clear();
  • js使用cookie保存token(cookie在http请求中,随着请求发送到服务器)

    • 保存token: sessionStorage.setItem("token","value");
    • 获取token: sessionStorage.getItem("token")
    • 删除: sessionStorage.removeItem("key");
    • 删除保存的所有数据: sessionStorage.clear()
  • 前端每次路由跳转, 判断 localStroage 有无 token ,没有则跳转到登录页,有则请求获取用户信息,改变登录状态

  • 每次请求接口,在 请求头里携带 token

$.ajax({
    type: "post",
    url: areaComp,
    dataType: "json",
    contentType: "application/json",
    data: data,
    async: false,
        //再次添加头部信息
    beforeSend: function(request) {
        request.setRequestHeader("token", token);
    },
    success: function (data){})
  • 后端接口 判断 请求头有无 token,没有或者 token 过期,返回401

  • 前端得到 401 状态码,重定向 到登录页面

  • 与cookie相比较的优势:

  • 支持跨域访问 ,将token置于请求头中,而cookie是不支持跨域访问的;

  • 无状态化, 服务端无需存储token ,只需要验证token信息是否正确即可,而session需要在服务端存储,一般是通过cookie中的sessionID在服务端查找对应的session;

  • 无需绑定到一个特殊的身份验证 方案(传统的用户名密码登陆),只需要生成的token是符合我们预期设定的即可;

  • 更适用于移动端 (Android,iOS,小程序等等),像这种原生平台不支持cookie,比如说微信小程序,每一次请求都是一次会话,当然我们可以每次去手动为他添加cookie,详情请查看博主另一篇博客;

  • 避免CSRF跨站伪造攻击 ,还是因为不依赖cookie;

  • 非常适用于RESTful API ,这样可以轻易与各种后端(java,.net,python…)相结合,去耦合

参考代码
  • cookie操作相关方法
/**
 * 写入cookie
 *
 * @param name
 * @param value
 */
function setCookie(name, value) {
    var Days = 30;
    var exp = new Date();
    exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
    document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + ";path=/";

}

/**
 * 读取cookie
 * @param name
 * @returns {null}
 */
function getCookie(name) {
    var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
    if (arr = document.cookie.match(reg))
        return unescape(arr[2]);
    else
        return null;
}

/**
 * 删除cookie
 * @param name
 */
function delCookie(name) {
    var exp = new Date();
    exp.setTime(exp.getTime() - 1);
    if (cval != null)
        document.cookie = name + "=" + "xxxx;expires=" + exp.toUTCString();
}

/**
 * 检查cookie
 */
function checkCookie() {
    if (getCookie("token") == null) {
        window.location.href = "login.html";
    }
}

/**
 * 检查cookie
 */
function checkResultCode(code) {
    if (code == 402) {
        window.location.href = "login.html";
    }
}
  • jquery简写

  • 先引入jquery,再引入:jquery.cookie.js;下载:http://plugins.jquery.com/cookie/

// 设置cookie expires是保存时间,单位是天  path : 能够访问的页面 / 表示根路径(全部页面都能访问)
$.cookie('token', 'token_value', { expires: 10, path: '/' });
// 获取cookie
$.cookie("token")
// 删除cookie
$.cookie("名称",null)
$.cookie('the_cookie','the_value',{
    expires:7, //expires:(Number|Date)有效期;设置一个整数时,单位是天;也可以设置一个日期对象作为Cookie的过期日期;
    path:'/', //path:(String)创建该Cookie的页面路径
    domain:'jquery.com', //path:(String)创建该Cookie的页面路径
    secure:true //(Booblean)如果设为true,那么此Cookie的传输会要求一个安全协议,例如:HTTPS;
}) 
  • login
function login() {
    var userName = $("#username").val();
    var password = $("#password").val();
    var data = { "username": userName, "password": password }
    //console.log(data);
    $.ajax({
        type: "POST", //方法类型
        dataType: "json", //预期服务器返回的数据类型
        url: "http://localhost:8082/user/login",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(data),
        success: function(result) {
            console.log(result);
            if (result.status == 200) {
                setCookie("token", result.data.userToken);
                setCookie("username",username);
                window.location.href = "index.html";
            };
            if (result.status == 406 ) {
                alert("登陆失败!请检查账号和密码!");
                return;
            }
        },
        error: function() {
            alert("接口异常,请联系管理员!");
            return;
        }
    });
}
  • 对于某些页面必须登录才能访问,使用文档加载事件
<body class="hold-transition sidebar-mini" onLoad="checkCookie();">
  • ajax请求是携带token,比如删除用户
function userDel() {
   $.ajax({
      type: "DELETE",
      url: "users/delete/1",
      contentType: "application/json",
      beforeSend: function(request) {
          //设置header值
          request.setRequestHeader("token", getCookie("token"));
      },
      success: function(r) {
          if (r.resultCode == 200) {
            console.log("删除成功")
          } else {
            console.log("删除失败")
          }
      }
  });
}

接口注意事项

  • 必须登录 @TokenToUser User oldUser
  • 先判断参数
  • getErrorResult
    • code, msg
    • 1, msg
  • getSuccessResult
    • 非String,传数据 (data)
    • 传String msg (msg)
      • 传data (Object)
    • 非实体类
      • JSONObject jsonObject = new JSONObject();
        jsonObject.put("question",user.getQuestion());
@RestController
public class AdminManagerController {
    @Resource
    private UserService userService;

    @GetMapping("/user/list")
    public Result getUsers(@RequestParam(required = false) Map<String, Object> params, @TokenToUser User oldUser){
        if (StringUtils.isEmpty(params.get("page")) || StringUtils.isEmpty(params.get("limit"))) {
            return ResultGenerator.getErrorResult(Constants.RESULT_CODE_PARAM_ERROR, "参数异常!");
        }
        if (oldUser==null){
            return ResultGenerator.getErrorResult(Constants.RESULT_CODE_NOT_LOGIN,"用户未登录,请登录");
        }
        if (!"A".equals(oldUser.getRole())){
            return ResultGenerator.getErrorResult("没有权限");
        }
        PageUtil pageUtil = new PageUtil(params);
        System.out.println(params);
        return ResultGenerator.getSuccessResult(userService.getUserPage(pageUtil));
    }

    @PostMapping("/user/login")
    public Result login(@RequestBody JSONObject jsonParam){
        String username = jsonParam.getString("username");
        String password = jsonParam.getString("password");
    }

    @PostMapping("/register")
    public Result register(@RequestBody  User user){
    
    }
}

  • sql语句
    • update():SET 最后加 update_time=NOW()
    • 传参:#{username}
    • 命名问题:方法名不能重复

mybatis注解使用

//单参数查询注解
@Select("select * from t_user where id = #{id}")
public User getUserById(Integer id);
//多参数查询注解 当 #{} 的变量与@Param()一致默认为变量名
@Select("select * from t_user where username like CONCAT('%',#{name},'%') and employeeNum like CONCAT('%',#{num},'%')")
public List<User> searchUsers(@Param("name") String name,@Param("num") String num);

// 属性变量有类的注解
@Select("select * from t_job where id = #{jobId}")
@Results({
  @Result(property="javabean变量",column="数据库字段名",one=@One(select="全类名"))
})
public Job getJobById(Integer jobId);

//参数为Map的注解,返回值为类。
 @Select("select m.user_name as userName from m_user m,m_job j where m.user_id=m.id and j.job_id=#{jobId}")
public List<myJob>  getJobByMap(Map map);

//参数为Map,返回值为List<Map>的注解,此时不需要bean类来对应字段
@Select("select * from m_user  whereand j.job_id like CONCAT('%',#{jobId},'%')")
public List<Map>  getMyJobs(Map map);


@Select("select t_id as id,t_username username,t_password as password from t_user")
//@ResultType(User.class)// 自动识别bean类 返回值需要跟表字段名一致,或者sql 使用as 
@Results({@Result(property="username",column="t_username")
        ,@Result(property="password",column="t_password") }) //使用Results来对应属性值
public List<User> selectAll();

mysql问题

  • 安装:需要以管理员的身份运行
  • mysqld install 需要再mysql\bin下运行
  • mysqld remove 是卸载
  • 时间不对,相差8个小时
set global time_zone = '+8:00';
flush privileges;
select now(); -- 查看当前时间是否为系统时间
  • java访问数据库设置时区
jdbc:mysql://localhost:3306/db_es?useSSL=false&serverTimezone=Asia/Shanghai
  • 修改密码 alter user 'root'@'localhost' identified with mysql_native_password by '123456';

支付宝沙盒模拟

  • 导包
		<dependency>
		    <groupId>com.alipay.sdk</groupId>
		    <artifactId>alipay-sdk-java</artifactId>
		    <version>3.0.0</version>
		</dependency>
  • 配置
# 支付宝网关名、partnerId和appId
open_api_domain=https://openapi.alipaydev.com/gateway.do
mcloud_api_domain=http://mcloudmonitor.com/gateway.do
pid=
app_id=
# RSA私钥、公钥和支付宝公钥
merchant_private_key=

public_key=
#SHA1withRsa对应支付宝公钥
#alipay_public_key = 
#SHA256withRsa对应支付宝公钥
alipay_public_key=

# 签名类型: RSA->SHA1withRsa,RSA2->SHA256withRsa
sign_type=RSA2
#页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
return_url=http://192.168.1.20:8082/user/pay/return
#服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
notify_url=http://192.168.1.20:8082/user/pay/notify
charset=utf-8
format=json
logPath=E:\\
# 当面付最大查询次数和查询间隔(毫秒)
max_query_retry=5
query_duration=5000
# 当面付最大撤销次数和撤销间隔(毫秒)
max_cancel_retry=3
cancel_duration=2000
# 交易保障线程第一次调度延迟和调度间隔(秒)
heartbeat_delay=5
heartbeat_duration=900
package com.ysu.shop.config;

import java.io.FileWriter;
import java.io.IOException;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "")
@PropertySource(value = "classpath:zfbinfo.properties", encoding = "utf-8")
public class AlipayConfig {

    // 支付宝网关
    private String openApiDomain;

    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    private String appId;

    // 商户私钥,您的PKCS8格式RSA2私钥
    private String merchantPrivateKey;

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    private String alipayPublicKey;

    // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    private String notifyUrl;

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    private String returnUrl;

    // 签名方式
    private String signType;

    // 字符编码格式
    private String charset;

    private String logPath;

    private String format;

    public void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(logPath + "alipay_log_" + System.currentTimeMillis() + ".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public String getOpenApiDomain() {
        return openApiDomain;
    }

    public void setOpenApiDomain(String openApiDomain) {
        this.openApiDomain = openApiDomain;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getMerchantPrivateKey() {
        return merchantPrivateKey;
    }

    public void setMerchantPrivateKey(String merchantPrivateKey) {
        this.merchantPrivateKey = merchantPrivateKey;
    }

    public String getAlipayPublicKey() {
        return alipayPublicKey;
    }

    public void setAlipayPublicKey(String alipayPublicKey) {
        this.alipayPublicKey = alipayPublicKey;
    }

    public String getNotifyUrl() {
        return notifyUrl;
    }

    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }

    public String getReturnUrl() {
        return returnUrl;
    }

    public void setReturnUrl(String returnUrl) {
        this.returnUrl = returnUrl;
    }

    public String getSignType() {
        return signType;
    }

    public void setSignType(String signType) {
        this.signType = signType;
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public String getLogPath() {
        return logPath;
    }

    public void setLogPath(String logPath) {
        this.logPath = logPath;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }
}

  • 测试
package com.ysu.shop.controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.ysu.shop.annotation.TokenToUser;
import com.ysu.shop.config.AlipayConfig;
import com.ysu.shop.pojo.Orders;
import com.ysu.shop.pojo.Pay;
import com.ysu.shop.pojo.User;
import com.ysu.shop.service.OrderService;
import com.ysu.shop.service.PayService;
import com.ysu.shop.util.CheckUtil;
import com.ysu.shop.util.Result;
import com.ysu.shop.util.ResultGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
// import springfox.documentation.annotations.ApiIgnore;
import io.swagger.annotations.*;
import springfox.documentation.annotations.ApiIgnore;
@RestController
@RequestMapping("/user")
@SuppressWarnings("rawtypes")
@Api(value="/user/pay",tags="支付模块")
public class PayController {

    private Logger log = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private AlipayConfig alipayConfig;

    @Resource
    private OrderService orderService;

    @Resource
    private PayService payService;
    /**
     * 测试订单号15932466191022,15933410263042
        localhost:8082/user/payByAli/15933410263042
     * url localhost:8082/user/payByAli/15932591648892
     * @param orderNo
     * @param request
     * @param response
     * @return 
     * @throws Exception
     */
    @RequestMapping("/payByAli/{orderNo}")
    public void payController(@PathVariable String orderNo, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        Orders order = orderService.getOrderByOrderNo(orderNo);//#
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getOpenApiDomain(), alipayConfig.getAppId(),
                alipayConfig.getMerchantPrivateKey(), alipayConfig.getFormat(), alipayConfig.getCharset(),
                alipayConfig.getAlipayPublicKey(), alipayConfig.getSignType()); // 获得初始化的AlipayClient
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();// 创建API对应的request
        alipayRequest.setReturnUrl(alipayConfig.getReturnUrl());
        alipayRequest.setNotifyUrl(alipayConfig.getNotifyUrl());// 在公共参数中设置回跳和通知地址
        alipayRequest.setBizContent("{" + "    \"out_trade_no\":\"" + orderNo + "\","
                + "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," + "    \"total_amount\":\""
                + order.getPayment().add(order.getPostage()) + "\"," + "    \"subject\":\"" + "欢迎使用睿乐购商城" + "\","
                + "    \"body\":\"" + "遇到问题,客服7*24为你解答问题" + "\","
                + "    \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\","
                + "    \"extend_params\":{" + "    \"sys_service_provider_id\":\"2088511833207846\"" + "    }" + "  }");// 填充业务参数
        String form = "";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            Pay pay = new Pay(order.getUser_id(),orderNo,"1");
            pay.setPlatform_status("1");
            payService.addPay(pay);
            log.debug("支付失败");
            
        }
        response.setContentType("text/html;charset=" + alipayConfig.getCharset());
        response.getWriter().write(form);// 直接将完整的表单html输出到页面
        response.getWriter().flush();
        response.getWriter().close();
    }

    @RequestMapping("/pay/return")
    public void  paySuccess(String out_trade_no,HttpServletResponse response,HttpServletRequest request) throws Exception{
        Map<String, String> map = new HashMap<String, String>();
		Map<String, String[]> requestParams = request.getParameterMap();
		for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
			String name = iter.next();
			String[] values = requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			map.put(name, valueStr);
        }
        Orders order = orderService.getOrderByOrderNo(out_trade_no);
      
        Pay pay = new Pay(order.getUser_id(),out_trade_no,"1");
      
		boolean signVerified = false;
		try {
            signVerified = AlipaySignature.rsaCheckV1(map, alipayConfig.getAlipayPublicKey(),
                alipayConfig.getCharset(), alipayConfig.getSignType());
		} catch (com.alipay.api.AlipayApiException e) {
			log.info("支付回调异常",e);
            // 验签发生异常,则直接返回失败
            pay.setPlatform_status("1");
            payService.addPay(pay);
            response.sendRedirect("/rlg/payFail.html");
		}
		if (signVerified) {
            orderService.payByOrderNo(out_trade_no);
            payService.addPay(pay);
			response.sendRedirect("http://localhost:8082/rlg/paySuccess.html");
		} else {
			log.info("验证失败");
			pay.setPlatform_status("1");
            payService.addPay(pay);
            response.sendRedirect("http://localhost:8082/rlg/payFail.html");
		}
    }

    @RequestMapping("/pay/notify")
    public void payNotify(String out_trade_no,HttpServletResponse response,HttpServletRequest request
        )throws Exception {
            Map<String, String> map = new HashMap<String, String>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = iter.next();
                String[] values = requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) { 
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                map.put(name, valueStr);
            }
            Orders order = orderService.getOrderByOrderNo(out_trade_no);
          
            Pay pay = new Pay(order.getUser_id(),out_trade_no,"1");
          
            boolean signVerified = false;
            try {
                signVerified = AlipaySignature.rsaCheckV1(map, alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getCharset(), alipayConfig.getSignType());
            } catch (com.alipay.api.AlipayApiException e) {
                log.info("支付回调异常",e);
                // 验签发生异常,则直接返回失败
                pay.setPlatform_status("1");
                payService.addPay(pay);
                response.sendRedirect("/rlg/payFail.html");
            }
            if (signVerified) {
                orderService.payByOrderNo(out_trade_no);
                payService.addPay(pay);
                response.sendRedirect("/rlg/paySuccess.html");
            } else {
                log.info("验证失败");
                pay.setPlatform_status("1");
                payService.addPay(pay);
                response.sendRedirect("/rlg/payFail.html");
            }
    }

}
  • 回调参数实例
{
    "charset":"utf-8",
    "out_trade_no":"15936564583112",
    "method":"alipay.trade.page.pay.return",
    "total_amount":"112.00",
    "sign":"jIG9ctLKjlGW2z7v2%2FF1fhXFGwtFsidrqZzNENykIu804IvQFKzqw%2FG7TfKQE3NHNlsYaJ4FuQEUM45mK8J2sTIJy4gXDnLCsFEXwsycSP8GSWf3Jp4dCLEPteI%2F20wETa8Mqx0ySYliEcywOxc33AJTHMMKf4x5bjS3ccvqx%2BrJGLeHE8NrX%2FZEBp%2Ba1tQ7O2CRVv9ADiAMfoyyAQ47laiP5HnGKVa%2FHuBwTd%2FnLxE8dOH%2BtZp1w1MDKbm0D8Cn784gctmxGZAWUmiE3Y7U%2Bn1VNCQlSF7Oo6cd63ftJ2QJBedOWpH3RrXtGPnJlIFruAnFDUt%2F3lWv9N2qtZd9hQ%3D%3D",
    "trade_no":"2020070222001435400500635866",
    "auth_app_id":"2016102700771189",
    "version":"1.0",
    "app_id":"2016102700771189",
    "sign_type":"RSA2",
    "seller_id":"2088102181269576",
    "timestamp":"2020-07-02+10%3A20%3A38"
}

集成Swagger2文档

集成admin

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值