1.项目简介
Gitee官网: https://gitee.com/lwt121788/hot-port-resault
基本环境:
SpringBoot 2.7.7 + Thymeleaf 2.7.7 + mail + aliyunpay
Maven依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.7</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.jsxs</groupId> <artifactId>HotPotRestaurant</artifactId> <version>0.0.1-SNAPSHOT</version> <name>HotPotRestaurant</name> <description>Demo project for Spring Boot</description> <properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 修改成我们所需要的mysql版本 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!-- thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.7.7</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--邮箱任务--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- 阿里巴巴云支付 --> <dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
项目介绍:
本项目设置的目的主要是: “练习自己的springBoot+thymeleaf”。在《江道原火锅店》项目中我们有三大特色:“1.页面逻辑好看、2.邮箱联系卖家、3.支付宝支付、4.门店导航”。页面我们采用 "模板之家"但对其页面进行修改调整,邮箱和支付宝较为重要
2.收获成果
邮箱发送
application.properties
# 邮箱 # 用户名 spring.mail.username=2261203961@qq.com # 授权码 spring.mail.password=fvjumghtshkyechc # 链接主机 spring.mail.host=smtp.qq.com # 开启加密验证 spring.mail.properties.mail.smtp.ssl.enable=true
controller层
@Resource JavaMailSenderImpl sender; // 发送邮件-功能 @RequestMapping("/sendMail") @ResponseBody public String hotPotRestaurantSend(String emails,String information){ if (emails.trim().substring(emails.length()-7).equals("@qq.com")){ SimpleMailMessage message = new SimpleMailMessage(); message.setSubject("火锅店-固墙店--用户联系"); // 主题 message.setText(information); // 文章内容 message.setFrom(emails.trim()); // 发送人 message.setTo("2261203961@qq.com"); sender.send(message); return "信息已发送"; }else { return "对不起您的邮箱不支持被Java所调用.请直接联系咨询热线: 18844129422 或开启STMP协议"; } }
地图
地图html页面
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>吉先生的店-北京</title> <style type="text/css"> #container{ /*地图(容器)显示大小*/ width:100%; height:100%; } </style> <!--引入Javascript API GL,参数说明参见下文--> <script src="https://map.qq.com/api/gljs?v=1.exp&key=XZUBZ-LJELP-XKEDX-V4N4F-TUSWS-NAFCV"></script> <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=XZUBZ-LJELP-XKEDX-V4N4F-TUSWS-NAFCV"></script> <script> //地图初始化函数,本例取名为init,开发者可根据实际情况定义 function initMap() { //定义地图中心点坐标 var center = new TMap.LatLng(39.984120, 116.307484) //定义map变量,调用 TMap.Map() 构造函数创建地图 var map = new TMap.Map(document.getElementById('container'), { center: center,//设置地图中心点坐标 zoom: 17.2, //设置地图缩放级别 pitch: 43.5, //设置俯仰角 rotation: 45 //设置地图旋转角度 }); } function loadScript() { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://map.qq.com/api/gljs?v=1.exp&key=XZUBZ-LJELP-XKEDX-V4N4F-TUSWS-NAFCV&callback=initMap"; document.body.appendChild(script); } window.onload = loadScript; </script> </head> <!-- 页面载入后,调用init函数 --> <body onload="initMap()"> <!-- 定义地图显示容器 --> <div id="container"></div> </body> </html>
利用RestFul风格降低controller冗余性
// 门店的地图 @RequestMapping({"/GPS/{address}","/GPS.html/{address}"}) public String hotPotRestaurantBranch(@PathVariable("address") String address){ return "GPS/GPS_"+address; }
支付宝支付
config配置类
package com.jsxs.config; import java.io.FileWriter; import java.io.IOException; public class AlipayConfig { // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID public static String APP_ID = "2021000122620920"; // 商户私钥,您的PKCS8格式RSA2私钥 public static String APP_PRIVATE_KEY = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQChoH3Kn7TelVQCBswpjMlu2c8Jr7ATH/JAs3COEBzDDespl/lAhUs8+sxCCmSySXN+uYshA6+Akov4UXF6+7XgMQTRHjcdZINT5U/ZnxBZlF1fALUXzqS41cOjHrRkkNK+Qs2Yi1jB9htWFJOmGJALU8vo7Qy9evJoW97J4sie+5lYviaawuGBF0pGukmiByk4e3gFsMkh4y73zMYnqbpoZGKLSlHBABmeq6ladIEf5A/xUTHcV6Un0c5B4YZH8d0t4voKYhnf0B51l51C17+oOHqyiVJHpl58vwbCIiirqTKTR8SqwoPPBpodoOC2F/IqanlXq4823nTodVEXCYOhAgMBAAECggEBAI2MtR4jyI+3UB+GPH+XIULH1p6xEw9sxwkLHeQNEGNzaSTASDbNhhsduo2L9Kx/z3qInOSJCccckSEkkrIWiC6UP5e1UqeXQ7zR86Cvwe3yFeQCBpeXDoQiEnhlh68bdrXSY6TZRR55n29ADh9FG8IP3WFdWe8IIgxriS5eQz2XzYOmSJAQsW69LreD+q5Lp97VPEjLAfPOaeMfsNSoaP40pZ+2/uQYsaaPcq0aIVO1idgxqzsJcSdtncbbYGBSYH8b248zjhqMX/PwgK/0jQBsvXJAG8IJLW9E7i5skFbQzqtxFCk4onfg8u00pWopMkEugUlQcBROh3f/ZZ0/mtECgYEA4W2nhxrc+VqsLl6/LwsCplyLlq6W26ihEePCYgcYcJHEmBDkRnBbmWyclsIDIJ+VEqaZ9VRwMfUeJf+IkxsWgxUEfApPHyzU+AVgpD6yZUEQog/Yql3m0A+KVBbyXGzrrd3gixQeSNV9FAvOZnPhcosot6Ao+O/BmcV89cL/+fcCgYEAt4vM+X8tyAnzTOmFYR95BVY7XooBNKWFInEJ2ykbmiD+8AOOo3wRwEQJpLp2RbtHKwvUGw7eNSAd8sddUwk751HQ3h0fiJQ2UUXpak3lGoKWWEY2ofHTeB+WTKOcIjk0WbX1GRuNnAJssrK2wkUlHpwz4h3o2GAPgw/07JGVSScCgYAvEou5/ZUJCLMNl8FKXH04KfkIBPsBcUv5BVtQxvSGhRnNOzG/t7SY7AIixO6MQGaLl3hsry4icHHUM3DcbvqbcqcWE70D4IO0KsNMaL8tv5FuleqDYMpSxfv3pTcEr8Xi74L058WPJe1RY0m9QRNhrMda2LnViZMevgti8k4rbwKBgQCs2EYKni1qt5Qa1b35HD5HPFFkUemYvlaFfJWfgTKxDmmFdJQaeHfu6yN5sO439IisjNMNOA8hUEFjo0LLM2LqDy32PM65O3l7R67roLcjI96Y+mXwU16lPHm5aklaISyfXq6VGlFcnRvnnExm3d562PYy9Z+UQ8HX1mr7bI18+QKBgQDO2bDicEShwtWcnT1Nooa4J0v/LILC1exBSX12OdjVCPkn52x/RmI7nQu/nzfwJB8/Spw5Kh93BGZr4qDMFSfE81L9ApWAtvQpbZ8oz22SRrCxno2rKHO4I2Bh50BtXjtTfO4u9TBIXdV1lr9+ivQCsup6KeslS9+xWsP92n58IQ==\n"; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx0R/5SJaYXD9uBTfzbQJvYIh07GHVoeppfndAaoy/HNJrlot1zU9YfRl+1gJVN1J8yAuVBoXRVPpIiMi8K/fVjWWk7T6SbCRbBEKe0YVP/zUSrNP5FmYA+OLYPSsoy19DNbzkdtQA05mtoHcPNf5lzgeq6phLLWwQtpBbxb9gu29HT3oAfyio6PuslEdnRWVV+fMVK0BkgEa/XNdC8nKMgeeo9uzuzksW6INdVVN8DlElEr4GChAU6VN0FfK5szH0rTYYxAclJPwLEudVWF3hSXqf1kafXTGfKBCRYTYCoGywm0fQNXH7fZuqYpOu7duKkQJDB+RNxOMWRmU4cemdwIDAQAB\n"; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = "http://www.jsxs1.cn:8089/"; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面) public static String return_url = "http://www.jsxs1.cn:8089/"; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String CHARSET = "utf-8"; // 支付宝网关,这是沙箱的网关(你自己的) public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do"; // 支付宝网关 public static String log_path = "C:\\"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ /** * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库) * @param sWord 要写入日志里的文本内容 */ public static void logResult(String sWord) { FileWriter writer = null; try { writer = new FileWriter(log_path + "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(); } } } } }
控制层使用Result风格
package com.jsxs.controller; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.request.AlipayTradePagePayRequest; import com.jsxs.config.AlipayConfig; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; @Controller public class PayController { @RequestMapping("/pay/{payMoney}") public void payController(HttpServletRequest request, HttpServletResponse response, @PathVariable("payMoney") String payMoney) throws IOException { //获得初始化的AlipayClient AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type); //设置请求参数 AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); alipayRequest.setNotifyUrl(AlipayConfig.notify_url); //商户订单号,商户网站订单系统中唯一订单号,必填 // 订单号 order String order = UUID.randomUUID().toString().replaceAll("-", ""); // 付款金额 money //订单名称 String orderName="JSXS-JDYHGD"; String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format(new Date()); //商品描述 String orderDescription=format+""; // String out_trade_no = new String(order.getBytes("ISO-8859-1"), "UTF-8"); //付款金额,必填 String total_amount = new String(payMoney.getBytes("ISO-8859-1"), "UTF-8"); //订单名称,必填 String subject = new String(orderName.getBytes("ISO-8859-1"), "gbk"); //商品描述,可空 String body = new String(orderDescription.getBytes("ISO-8859-1"), "gbk"); alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); //若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明 //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\"," // + "\"total_amount\":\""+ total_amount +"\"," // + "\"subject\":\""+ subject +"\"," // + "\"body\":\""+ body +"\"," // + "\"timeout_express\":\"10m\"," // + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节 //请求 String form = ""; try { form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 } catch (AlipayApiException e) { e.printStackTrace(); } response.setContentType("text/html;charset=" + AlipayConfig.CHARSET); response.getWriter().write(form);//直接将完整的表单html输出到页面 response.getWriter().flush(); response.getWriter().close(); } @RequestMapping("/preverpay") public String toTest(){ return "aliyunpay"; } }
html 定价
<ul class="clearfix"> <li> <a th:href="@{/pay/10}"> <figure><img src="/img/kaorou1.png"/></figure> <p>经典烤肉10.00元</p> </a> </li> <li> <a th:href="@{/pay/19}"> <figure><img src="/img/kaorou2.png"/></figure> <p>烈火烤肉19.00元</p> </a> </li> <li> <a th:href="@{/pay/29.99}"> <figure><img src="/img/kaorou3.png"/></figure> <p>五香烤肉29.99元</p> </a> </li> <li> <a th:href="@{/pay/46.10}"> <figure><img src="/img/kaorou4.png"/></figure> <p>青醋烤肉46.10元</p> </a> </li> <li> <a th:href="@{/pay/100.20}"> <figure><img src="/img/kaorou5.png"/></figure> <p>嘻嘻烤肉100.20元</p> </a> </li> <li> <a th:href="@{/pay/99.99}"> <figure><img src="/img/kaorou6.png"/></figure> <p>暮春烤肉99.99元</p> </a> </li> </ul>