睿乐购电商课程设计——总结 r囧r小猫 2023-02-23 03:38 53阅读 0赞 ### 睿乐购电商课程设计——总结 ### * * * 项目文件目录说明 * 命名说明与注意事项 * ajax参考 * 问题记录 * jquery 获取表单数据 * 前后端分离方案 * * session与cookie * token * * 参考代码 * 接口注意事项 * mybatis注解使用 * mysql问题 * 支付宝沙盒模拟 * 集成Swagger2文档 * 集成admin * 参考文档 ### 项目文件目录说明 ### * 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; } }); } ### 问题记录 ### * 数据库的导入(6.18): `source sql文件位置` * [自定义注解解决Springboot发送post请求时string类型参数接收不到的问题(HandlerMethodArgumentResolver )][Springboot_post_string_HandlerMethodArgumentResolver] * springboot2 前台传送json数据,后台接收数据(6.18) * 可以对实体类进行封装,但String不行 * 使用JSONObject 获取json 再获取键值 * 需要在参数前加上`@RequestBody`注解 ### 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文档 ### * [访问地址][Link 1] ### 集成admin ### * [SpringBoot - 使用Spring Boot Admin进行服务监控教程1(监控信息可视化)][SpringBoot - _Spring Boot Admin_1] ### 参考文档 ### * [JS之document.cookie详解以及$.cookie的使用][JS_document.cookie_.cookie] * [MySQL<表单&集合查询>][MySQL] * [4种方法让SpringMVC接收多个对象][4_SpringMVC] * [常用的swagger2 注解说明文档][swagger2] * [MySQL 安装][MySQL 1] * [Swagger2 最全注解说明][Swagger2] * [Swagger注解-@ApiModel 和 @ApiModelProperty][Swagger_-_ApiModel _ _ApiModelProperty] * [Spring Boot使用支付宝支付][Spring Boot] * [用springboot对接支付宝支付接口的详细开发步骤总结][springboot] * [Java支付宝支付开发流程与原理【沙箱环境】【分布式事务解决方案】][Java] * [session、cookie与“记住我的登录状态”的功能的实现][session_cookie] [Springboot_post_string_HandlerMethodArgumentResolver]: https://blog.csdn.net/CNAHYZ/article/details/105129050 [Link 1]: http://localhost:8082/swagger-ui.html [SpringBoot - _Spring Boot Admin_1]: https://www.hangge.com/blog/cache/detail_2709.html [JS_document.cookie_.cookie]: https://www.cnblogs.com/zouhong/p/11821644.html [MySQL]: https://www.cnblogs.com/justdoitba/p/7620187.html [4_SpringMVC]: https://blog.csdn.net/bibili123/article/details/81123140 [swagger2]: https://blog.csdn.net/weixin_43703274/article/details/90900597 [MySQL 1]: https://www.runoob.com/mysql/mysql-install.html [Swagger2]: https://www.cnblogs.com/niudaben/p/11869869.html [Swagger_-_ApiModel _ _ApiModelProperty]: https://blog.csdn.net/dejunyang/article/details/89527348 [Spring Boot]: https://blog.csdn.net/qq_42005257/article/details/90638692 [springboot]: https://blog.csdn.net/Eknaij/article/details/96324432 [Java]: https://blog.csdn.net/itcats_cn/article/details/82723889 [session_cookie]: https://www.cnblogs.com/xlh-2014/p/8110685.html
相关 【畅购电商】项目总结 目录 1. 电商项目架构图 1.1 系统架构 1.2 技术架构 2. 介绍电商项目 2.1 后台和前台、后端和前端 2.2 Vue全家桶包含哪些技术? 2.3 什 布满荆棘的人生/ 2024年03月27日 17:27/ 0 赞/ 154 阅读
相关 畅购电商项目 1. 电商项目架构图 -------------------- 技术框架/技术选型 1.1 系统架构 ![b7df8ec6234340b2b3624095 妖狐艹你老母/ 2023年10月04日 21:27/ 0 赞/ 138 阅读
相关 睿乐购电商课程设计——图片上传 睿乐购电商课程设计——图片上传 图书前端 后台 图书前端 <body> <div class="x-bo 悠悠/ 2023年02月23日 03:39/ 0 赞/ 51 阅读
相关 睿乐购电商课程设计——商品模块 睿乐购电商课程设计——商品模块 商品详情页 商品搜索页 购物车 商品详情页 `detail.j ﹏ヽ暗。殇╰゛Y/ 2023年02月23日 03:38/ 0 赞/ 101 阅读
相关 睿乐购电商课程设计——用户模块 睿乐购电商课程设计——用户模块 mapper service control mapper 用 谁借莪1个温暖的怀抱¢/ 2023年02月22日 13:33/ 0 赞/ 98 阅读
相关 电商系列(一)课程介绍 1.1、淘宝架构 ![这里写图片描述][SouthEast] 1.2 、课程安排 ![这里写图片描述][SouthEast 1] 1.2 、课程学习与解决问题 £神魔★判官ぃ/ 2021年09月26日 13:26/ 0 赞/ 388 阅读
还没有评论,来说两句吧...