创建项目
-
选择
Spring Initializr
-
选择本机配置的
JDK
-
点击
Next
-
填写
Group
-
填写
Artifact
-
选择
Maven Project
-
选择本机配置的JDK版本
-
点击
Next
-
选择
Web
-
勾选
Spring Web
-
点击
Next
-
点击
Finish
-
打开启动文件
com/example/mybatis/MybatisApplication.java
-
右键 -> run
常见问题
问题描述:
https://start.spring.io 无法访问
解决方案:
可使用 https://start.aliyun.com 替换
环境配置
配置文件支持两种写法:*.properties
和*.yml
server:
port: 8080
context-path: /
读取环境配置信息
读取单条信息
- 更改配置文件后缀
将 'resources/application.properties' 文件更改为 'application.yml'
- 添加配置
uname: 张三
- 创建控制器
package com.demo.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestController { @Value("${uname}") private String uname; @RequestMapping("/") @ResponseBody public String test(){ return uname; } }
读取对象信息
- 添加配置
uconfig: uname: 张三 password: 123456
- 创建配置对象
package com.demo.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.io.Serializable; @ConfigurationProperties(prefix = "uconfig") @Component public class UConfig implements Serializable { private String uname; private String password; // 省略 getter/setter }
- 创建控制器
package com.demo.controller; import cn.est.config.UConfig; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class TestController { @Resource private UConfig uConfig; @RequestMapping("/") @ResponseBody public String test(){ return uConfig.getUname() + " : " + uConfig.getPassword(); } }
读取指定配置文件的信息
- 创建配置文件
# resources/user.properties uconfig.uname=张三 uconfig.password=123456
- 创建配置对象
package cn.est.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import java.io.Serializable; @ConfigurationProperties(prefix = "uconfig") @PropertySource("classpath:user.properties") @Component public class UConfig implements Serializable { private String uname; private String password; // 省略 getter/setter }
- 创建控制器
package com.demo.controller; import cn.est.config.UConfig; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class TestController { @Resource private UConfig uConfig; @RequestMapping("/") @ResponseBody public String test(){ return uConfig.getUname() + " : " + uConfig.getPassword(); } }
注意事项
@PropertySource 注解不支持 yml 配置文件,只支持 property 配置文件。如果希望 @PropertySource 支持 property 配置文件,需要对该注解进行重写。
如果读取 property 配置文件中的中文为乱码,请进行如下设置:
File -> Settings -> Editor -> File Encodings -> Properties Files(*.properties) -> 选择 UTF-8,并勾选后面的复选框
整合 MyBatis
- 添加依赖
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
- 环境配置
spring: datasource: url: jdbc:mysql://localhost:3306/est?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 driver-class-name: com.mysql.cj.jdbc.Driver username: root password: ok mybatis: mapper-locations: classpath:mapper/*.xml
- 创建 Mapper 映射
<!-- resources/mapper/TestMapper.xml --> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mybatis.mapper.TestMapper"> <select id="getCount" resultType="int"> SELECT COUNT(1) FROM users </select> </mapper>
- 创建 Mapper 接口
package com.example.mybatis.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface TestMapper { Integer getCount(); }
- 创建 controller
package com.example.mybatis.controller; import com.example.mybatis.mapper.TestMapper; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private TestMapper test; @RequestMapping("/") public Integer test(){ return testMapper.getCount(); } }
- 启动并访问
打开浏览器,访问:`http://localhost:8080/`
整合 Redis
- 引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.4.5.RELEASE</version> </dependency>
- 配置应用
redis: database: 0 host: 127.0.0.1 password: port: 6379
- 创建 Redis 工具类
package com.example.redis.utils; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component public class RedisUtils { @Resource private StringRedisTemplate stringRedisTemplate; /** * 写入数据 * * @param k 键 * @param v 值 */ public void set(String k, String v) { stringRedisTemplate.opsForValue().set(k, v); } /** * 写入临时数据 * @param k 键 * @param v 值 * @param t 有效期,单位:秒 */ public void set(String k, String v, long t) { stringRedisTemplate.opsForValue().set(k, v, t, TimeUnit.SECONDS); } /** * 获取数据 * * @param k 键 * @return 值 */ public String get(String k) { return stringRedisTemplate.opsForValue().get(k); } }
- 创建控制器
package com.example.redis.controller; import com.example.redis.utils.RedisUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; @Controller public class RedisController { @Resource private RedisUtils redisUtils; @ResponseBody @RequestMapping("/") public String test() { redisUtils.set("name", "张三"); return "success"; } }
整合 阿里云短信
- 阿里云短信线上操作
1. 注册阿里云账号
2. 进行实名认证
3. 开通短信服务
4. 添加签名
5. 添加模板
6. 创建 AccessKey
7. 查看AccessKey Secret - 导入依赖
<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.50</version> </dependency>
- 创建短信发送配置文件
ssm.properties
sms.accessKeyId=此处替填写'AccessKey ID' sms.secret=此处填写'AccessKey Secret' sms.RegionId=cn-hangzhou sms.domain=dysmsapi.aliyuncs.com sms.version=2017-05-25 sms.action=SendSms sms.signName=此处替换为'签名名称' sms.templateCode=此处替换为'模版CODE'
- 创建短信发送配置对象
package com.example.aliyunssm.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "sms") @PropertySource("classpath:ssm.properties") public class AliyunSSMConfig { private String accessKeyId; private String secret; private String RegionId; private String domain; private String version; private String action; private String signName; private String templateCode; // 省略getter/setter }
- 创建短信发送工具类
package com.example.aliyunssm.utils; import com.alibaba.fastjson.JSONObject; import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.http.MethodType; import com.aliyuncs.profile.DefaultProfile; import com.example.aliyunssm.config.AliyunSSMConfig; import org.springframework.stereotype.Component; import javax.annotation.Resource; /** * 短信发送工具类 */ @Component public class AliyunSSMUtils { @Resource private AliyunSSMConfig aliyunSSMConfig; /** * 发送短信的方法 * * @param phone 接收短信的手机号 * @param code 验证码 * @return */ public boolean sendMessage(String phone, String code) { DefaultProfile profile = DefaultProfile.getProfile(aliyunSSMConfig.getRegionId(), aliyunSSMConfig.getAccessKeyId(), aliyunSSMConfig.getSecret()); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); request.setSysMethod(MethodType.POST); request.setSysDomain(aliyunSSMConfig.getDomain()); request.setSysVersion(aliyunSSMConfig.getVersion()); request.setSysAction(aliyunSSMConfig.getAction()); request.putQueryParameter("RegionId", aliyunSSMConfig.getRegionId()); request.putQueryParameter("PhoneNumbers", phone); request.putQueryParameter("SignName", aliyunSSMConfig.getSignName()); request.putQueryParameter("TemplateCode", aliyunSSMConfig.getTemplateCode()); request.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}"); try { CommonResponse response = client.getCommonResponse(request); System.out.println(response.getData()); String status = JSONObject.parseObject(response.getData()).get("Code").toString(); return "OK".equals(status); } catch (ServerException e) { e.printStackTrace(); } catch (ClientException e) { e.printStackTrace(); } return false; } }
- 创建测试控制器类
package com.example.aliyunssm.controller; import com.example.aliyunssm.utils.AliyunSSMUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private AliyunSSMUtils aliyunSSMUtils; @RequestMapping("/") public Boolean test() { return aliyunSSMUtils.sendMessage("此处填写手机号", "0000") ? true : false; } }
整合 微信登陆
- 微信登陆线上操作
1. 注册微信开放者平台
2. 进行企业认证
3. 创建网页应用
4. 查看APPID - 导入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.50</version> </dependency>
- 创建微信登陆配置文件
wechat.openUrl=https://open.weixin.qq.com/connect/qrconnect wechat.appid=此处填写APPID wechat.redirectUri=http://localhost:8080/wechat/callback wechat.responseType=code wechat.scope=snsapi_login wechat.state=STATE#wechat_redirect wechat.accessTokenUrl=https://api.weixin.qq.com/sns/oauth2/access_token wechat.secret=此处填写SECRET wechat.grantType=authorization_code wechat.userInfoUrl=https://api.weixin.qq.com/sns/userinfo
- 创建微信配置文件对象类
package com.example.wxlogin.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "wechat") @PropertySource("classpath:wxlogin.properties") public class WechatConfig { private String appid; private String redirectUri; private String responseType; private String scope; private String state; private String openUrl; private String accessTokenUrl; private String secret; private String grantType; private String userInfoUrl; // 省略getter/setter }
- 创建URL工具类
package com.example.wxlogin.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class UrlUtils { /** * 获取url网址返回的数据内容 * * @param urlStr * @return */ public static String loadURL(String urlStr) { try { URL url = new URL(urlStr); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.connect(); InputStream inputStream = urlConnection.getInputStream(); String responseStr = ConvertToString(inputStream); return responseStr; } catch (IOException e) { e.printStackTrace(); return null; } } private static String ConvertToString(InputStream inputStream) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); StringBuilder result = new StringBuilder(); String line = null; try { while ((line = bufferedReader.readLine()) != null) { result.append(line + "\n"); } } catch (IOException e) { e.printStackTrace(); } finally { try { inputStreamReader.close(); inputStream.close(); bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } return result.toString(); } }
- 添加微信登陆控制器方法
package com.example.wxlogin.controller; import com.alibaba.fastjson.JSONObject; import com.example.wxlogin.config.WechatConfig; import com.example.wxlogin.utils.UrlUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @RestController public class TestController { @Resource private WechatConfig wechatConfig; /** * 显示微信登陆扫码界面 * * @param response * @throws Exception */ @RequestMapping("/wechat/login") public void wechat(HttpServletResponse response) throws Exception { StringBuffer wxsb = new StringBuffer(wechatConfig.getOpenUrl()); wxsb.append("?appid=" + wechatConfig.getAppid()); wxsb.append("&redirect_uri=" + wechatConfig.getRedirectUri()); wxsb.append("&response_type=" + wechatConfig.getResponseType()); wxsb.append("&scope=" + wechatConfig.getScope()); wxsb.append("&state=" + wechatConfig.getState()); response.sendRedirect(wxsb.toString()); } /** * 用户手机确认后回调函数 * * @param code * @throws Exception */ @RequestMapping("/wechat/callback") public Object callback(String code) throws Exception { // 构造请求URL StringBuffer wxsb = new StringBuffer(wechatConfig.getAccessTokenUrl()); wxsb.append("?appid=" + wechatConfig.getAppid()); wxsb.append("&secret=" + wechatConfig.getSecret()); wxsb.append("&code=" + code); wxsb.append("&grant_type=" + wechatConfig.getGrantType()); // 发送请求并获取accessToken和opendId String resp = UrlUtils.loadURL(wxsb.toString()); JSONObject jsonObject = JSONObject.parseObject(resp); String accessToken = jsonObject.getString("access_token"); String openId = jsonObject.getString("openid"); // 构造获取用户信息的URL StringBuffer usb = new StringBuffer(wechatConfig.getUserInfoUrl()); usb.append("?access_token=" + accessToken); usb.append("&openid=" + openId); // 发送请求并获取用户信息 String userInfo = UrlUtils.loadURL(usb.toString()); JSONObject userObject = JSONObject.parseObject(userInfo); return userObject; } }
整合 阿里云OSS文件服务
- 阿里云OSS线上操作
1. 登陆阿里云
2. 开通阿里云OSS服务
3. 进入OSS控制台
4. 进入 Bucket 列表
5. 创建 Bucket
6. 进入新创建的Bucket
7. 进入文件管理
8. 新建目录
9. 进入新创建的目录
10. 点击’上传文件’进行上传
11. 下载文件
- 添加依赖
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency>
- 创建oss配置文件
oss.endpoint=<EndPoint> oss.accessKeyId=<AccessKeyId> oss.accessKeySecret=<AccessKeySecret> oss.bucketName=<Bucket名称>
- 创建oss配置映射对象
package com.example.aliyunoss.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource("classpath:oss.properties") @ConfigurationProperties("oss") public class OSSConfig { private String accessKeyId; private String accessKeySecret; private String bucketName; private String endpoint; // 省略 getter/setter }
- 创建OSS工具类
package com.example.aliyunoss.utils; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.PutObjectRequest; import com.example.aliyunoss.config.OSSConfig; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.ByteArrayInputStream; import java.io.File; import java.net.URL; import java.util.Date; /** * 阿里云OSS服务器工具类 */ @Component public class OSSUtils { @Resource private OSSConfig ossConfig; /** * 文件上传 * * @param bytes 要上传文件的字节流 * @param objectName 目录名/文件名 */ public void uploadFile(byte[] bytes, String objectName) { OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), objectName, new ByteArrayInputStream(bytes)); ossClient.putObject(putObjectRequest); ossClient.shutdown(); } /** * 获取图片的临时URL * * @param objectName 目录名/文件名 * @return */ public String getTempUrl(String objectName) { OSS ossClient = new OSSClientBuilder().build(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()); Date expiration = new Date(new Date().getTime() + 3600 * 1000); URL url = ossClient.generatePresignedUrl(ossConfig.getBucketName(), objectName, expiration); ossClient.shutdown(); return url.toString(); } }
- 创建测试控制器
package com.example.aliyunoss.controller; import com.example.aliyunoss.utils.OSSUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.File; import java.io.IOException; @RestController public class TestController { @Resource private OSSUtils ossUtils; /** * 文件上传 * * @param multipartFile * @return */ @PostMapping("upload") public Boolean FileController(@RequestParam("file") MultipartFile multipartFile) throws IOException { File file = new File(multipartFile.getOriginalFilename()); // objectName 前不要有 / String objectName = "user/" + file.getName(); ossUtils.uploadFile(multipartFile.getBytes(), objectName); // 将objectName的值保存到数据库 return true; } /** * 获取文件地址 * * @return */ @GetMapping("show") public String showFile() { // objectName的值应该从数据库中读取 String objectName = "user/logo.png"; return ossUtils.getTempUrl(objectName); } }
整合 支付宝支付
- 支付宝支付线上操作
1. 生成签名
2. 开通沙箱环境 - 引入依赖
<dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-easysdk</artifactId> <version>2.0.1</version> </dependency>
- 创建配置文件
alipay.protocol=https alipay.gatewayHost=openapi.alipaydev.com alipay.signType=RSA2 alipay.appId=<APPID> alipay.merchantPrivateKey=<应用私钥> alipay.notifyUrl=<异步回调地址> alipay.returnUrl=<同步回调地址> alipay.encryptKey=<AES密钥> alipay.successUrl=<支付成功后的跳转页面>
- 创建配置文件对象类
package com.example.aliyay.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource("classpath:alipay.properties") @ConfigurationProperties("alipay") public class AliPayConfig { private String protocol; private String gatewayHost; private String signType; private String appId; private String merchantPrivateKey; private String notifyUrl; private String returnUrl; private String encryptKey; private String alipayPublicKey; private String successUrl; // 省略Getter/Setter }
- 创建工具类
package com.example.aliyay.utils; import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.factory.Factory.Payment; import com.alipay.easysdk.kernel.Config; import com.alipay.easysdk.kernel.util.ResponseChecker; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.example.aliyay.config.AliPayConfig; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Map; /** * 阿里支付工具类 */ @Component public class AliPayUtils { @Resource private AliPayConfig aliPayConfig; public AliPayConfig getAliPayConfig() { return aliPayConfig; } /** * 支付 * * @param sunject 项目名称 * @param payNo 订单号 * @param amount 支付金额 * @return */ public String toPcPay(String sunject, String payNo, String amount) { String result = ""; // 1. 设置参数(全局只需设置一次) Factory.setOptions(getOptions()); try { // 2. 发起API调用 AlipayTradePagePayResponse response = Payment.Page().pay(sunject, payNo, amount, aliPayConfig.getReturnUrl()); // 3. 处理响应或异常 if (ResponseChecker.success(response)) { result = response.body; System.out.println("调用成功"); } else { System.err.println("调用失败,原因:" + response.body); } } catch (Exception e) { System.err.println("调用遭遇异常,原因:" + e.getMessage()); throw new RuntimeException(e.getMessage(), e); } return result; } private Config getOptions() { Config config = new Config(); config.protocol = aliPayConfig.getProtocol(); config.gatewayHost = aliPayConfig.getGatewayHost(); config.signType = aliPayConfig.getSignType(); config.appId = aliPayConfig.getAppId(); config.merchantPrivateKey = aliPayConfig.getMerchantPrivateKey(); config.encryptKey = aliPayConfig.getEncryptKey(); config.notifyUrl = aliPayConfig.getNotifyUrl(); config.alipayPublicKey = aliPayConfig.getAlipayPublicKey(); return config; } /** * 验签 * * @param parameters * @return * @throws Exception */ public Boolean verify(Map<String, String> parameters) throws Exception { return Factory.Payment.Common().verifyNotify(parameters); } }
- 创建控制器类
package com.example.aliyay.controller; import com.example.aliyay.utils.AliPayUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; @Controller @RequestMapping("/api/pay") public class TestController { @Resource private AliPayUtils aliPayUtils; /** * 跳转到支付页 * * @param subject * @param payno * @param amount * @return */ @ResponseBody @PostMapping("/alipay") public String aliPay(String subject, String payno, String amount) { return aliPayUtils.toPcPay(subject, payno, amount); } /** * 支付成功回调函数 * * @param request * @return * @throws Exception */ @RequestMapping("/returnDeal") public String returnDeal(HttpServletRequest request) throws Exception { // 获取支付宝响应参数 Map<String, String[]> params = request.getParameterMap(); Map<String, String> paramters = new HashMap<>(); params.entrySet(); for (Map.Entry<String, String[]> entry : params.entrySet()) { paramters.put(entry.getKey(), entry.getValue()[0]); } // 验签 boolean flag = aliPayUtils.verify(paramters); if (!flag) { return "fail"; } return "redirect:" + aliPayUtils.getAliPayConfig().getSuccessUrl(); } }
- 创建测试支付表单
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>支付测试页</title> </head> <body> <form action="/api/pay/alipay" method="POST"> <label for="subject">项目名:</label> <input type="text" name="subject"> <br> <label for="payno">订单号:</label> <input type="text" name="payno"> <br> <label for="amount">订单金额:</label> <input type="text" name="amount"> <br> <input type="submit" value="支付"> </form> </body> </html>
- 搭建反向代理进行测试
整合 FastDFS
- 安装FastDFS
- 添加依赖
<dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>1.26.5</version> <!-- 因为logback和logf4j日志有冲突,因为要屏蔽掉logback --> <exclusions> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> </exclusion> </exclusions> </dependency>
- 添加配置
fdfs: so-timeout: 1501 connect-timeout: 601 thumb-image: width: 150 height: 150 web-server-url: 192.168.26.131 tracker-list: 192.168.26.131:22122
- 编写工具类
package com.example.utils; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig; import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray; import com.github.tobato.fastdfs.service.FastFileStorageClient; import org.springframework.context.annotation.Configuration; import javax.annotation.Resource; import java.io.InputStream; @Configuration public class FastDFSClient { @Resource private FastFileStorageClient storageClient; @Resource private ThumbImageConfig thumbImageConfig; /** * 文件上传 * * @param is 输入流 * @param size 文件大小 * @param suffixName 文件后缀 * @return */ public String upload(InputStream is, long size, String suffixName) { return storageClient.uploadFile(is, size, suffixName, null).getFullPath(); } /** * 上传缩略图 * * @param is 输入流 * @param size 文件大小 * @param suffixName 文件后缀 * @return */ public String uploadThumb(InputStream is, long size, String suffixName) { StorePath storePath = storageClient.uploadImageAndCrtThumbImage(is, size, suffixName, null); return thumbImageConfig.getThumbImagePath(storePath.getFullPath()); } /** * 下载文件 * * @param filePath 文件路径 * @return */ public byte[] download(String filePath) { StorePath storePath = StorePath.parseFromUrl((filePath)); return storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray()); } /** * 删除文件 * * @param filePath 文件路径 */ public void delete(String filePath) { storageClient.deleteFile(filePath); } }
- 编写测试控制器
package com.example.controller; import com.example.utils.FastDFSClient; import com.sun.org.apache.xpath.internal.operations.Bool; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; @RestController public class TestController { @Resource private FastDFSClient fastDFSClient; /** * 上传文件 * * @param file * @return */ @PostMapping("/upload") public String upload(MultipartFile file) throws IOException { return fastDFSClient.upload(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename())); } /** * 上传缩略图 * * @param file * @return * @throws IOException */ @PostMapping("/upload/thumb") public String uploadThumb(MultipartFile file) throws IOException { return fastDFSClient.uploadThumb(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename())); } /** * 下载操作 * * @param filePath 文件路径 * 例如:/group1/M00/00/00/wKgag13Ua12ACAGXAAGjHJfxiZc207.jpg * @param response * @throws IOException */ @PostMapping("/download") public void download(String filePath, HttpServletResponse response) throws IOException { byte[] bytes = fastDFSClient.download(filePath); IOUtils.write(bytes, response.getOutputStream()); } /** * 删除文件 * * @param filePath 文件路径 * 例如:/group1/M00/00/00/wKgag13Ua12ACAGXAAGjHJfxiZc207.jpg * @return */ @PostMapping("/delete") public Boolean delete(String filePath) { fastDFSClient.delete(filePath); return true; } }
整合 微信支付
-
添加依赖
wxpay.appID=此处填写APPID wxpay.mchID=此处填写MCHID wxpay.key=此处填写KEY wxpay.spbillCreateIp=127.0.0.1 wxpay.notifyUrl=http://外网地址/api/pay/wxPay/notify wxpay.successUrl=http://外网地址/api/pay/wxPay/success wxpay.failUrl=http://外网地址/api/pay/wxPay/fail wxpay.tradeType=NATIVE
-
下载微信SDK
链接:https://pan.baidu.com/s/1Mik6tAkjQhDCNC-lR6h2Zg 提取码:kkp2
-
将SDK里面的所有java文件拷贝到
sdk
包中
-
实现SDK中的
IWXPayDomain
接口package com.example.wxpay.config; import com.example.wxpay.sdk.IWXPayDomain; import com.example.wxpay.sdk.WXPayConfig; import com.example.wxpay.sdk.WXPayConstants; import org.springframework.stereotype.Component; @Component public class WXPayDomain implements IWXPayDomain { @Override public void report(String domain, long elapsedTimeMillis, Exception ex) { } @Override public DomainInfo getDomain(WXPayConfig config) { return new DomainInfo(WXPayConstants.DOMAIN_API, true); } }
-
创建配置对象类
package com.example.wxpay.config; import com.example.wxpay.sdk.IWXPayDomain; import com.example.wxpay.sdk.WXPayConfig; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.InputStream; @Component @ConfigurationProperties(prefix = "wxpay") @PropertySource("classpath:wechat.properties") public class WechatConfig extends WXPayConfig { private String appID; private String mchID; private String key; private String spbillCreateIp; private String notifyUrl; private String successUrl; private String failUrl; private String tradeType; @Resource private WXPayDomain wxPayDomain; @Override protected InputStream getCertStream() { return null; } @Override protected IWXPayDomain getWXPayDomain() { return wxPayDomain; } @Override public String getAppID() { return appID; } @Override public String getMchID() { return mchID; } @Override public String getKey() { return key; } // 省略部分Getter/Setter }
-
创建测试服务器
package com.example.wxpay.controller; import com.example.wxpay.config.WechatConfig; import com.example.wxpay.sdk.WXPay; import com.example.wxpay.sdk.WXPayConstants; import com.example.wxpay.sdk.WXPayUtil; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/api/pay") public class TestController { @Resource private WechatConfig wechatConfig; /** * 打开微信支付二维码 * * @param orderNo 订单编号 * @return */ @GetMapping("/wxpay/{orderNo}") public Map<String, Object> wxPay(@PathVariable String orderNo) { Map<String, Object> dto = new HashMap<>(); // 构建参数 Map<String, String> reqData = new HashMap<>(); reqData.put("body", "Java精品课"); // 商品名称 reqData.put("out_trade_no", orderNo); // 订单号 reqData.put("total_fee", "1"); // 付款金额,单位为分 reqData.put("spbill_create_ip", wechatConfig.getSpbillCreateIp()); reqData.put("notify_url", wechatConfig.getNotifyUrl()); reqData.put("trade_type", wechatConfig.getTradeType()); try { WXPay wxPay = new WXPay(wechatConfig, wechatConfig.getNotifyUrl(), false, false); // 调用统一下单接口 Map<String, String> stringMap = wxPay.unifiedOrder(reqData); // 校验签名 if (!WXPayUtil.isSignatureValid(stringMap, wechatConfig.getKey(), WXPayConstants.SignType.HMACSHA256)) { dto.put("code", 0); dto.put("msg", "签名校验失败"); } else if (!stringMap.get("return_code").equals(WXPayConstants.SUCCESS) || !stringMap.get("result_code").equals(WXPayConstants.SUCCESS)) { dto.put("code", 0); dto.put("msg", "获取付款二维码失败:" + stringMap.get("err_code_des").split(" ")[1]); } else { dto.put("code", 1); // 获取微信二维码code_url,需要转换成二维码图片 dto.put("code_url", stringMap.get("code_url")); } } catch (Exception e) { dto.put("code", 0); dto.put("msg", e.getMessage()); } return dto; } /** * 用户支付完成后的回调方法 * * @param request * @return */ @PostMapping("/wxPay/notify") public Map<String, Object> wxPayNotify(HttpServletRequest request) { Map<String, Object> dto = new HashMap<>(); // 接收微信回传信息 InputStream inputStream = null; BufferedReader reader = null; try { StringBuilder builder = new StringBuilder(); inputStream = request.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String line = ""; while ((line = reader.readLine()) != null) { builder.append(line); } String wxParamXml = builder.toString(); // 签名校验 if (!WXPayUtil.isSignatureValid(wxParamXml, wechatConfig.getKey())) { dto.put("code", 0); dto.put("msg", "签名校验失败"); } else { // 将xml字符串转为map对象 Map wxPayResult = WXPayUtil.xmlToMap(wxParamXml); dto.put("code", 1); dto.put("data", wxPayResult); } } catch (Exception e) { dto.put("code", 0); dto.put("msg", e.getMessage()); } finally { try { reader.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } return dto; } }
整合 MongoDB
- 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
- 配置环境
spring: data: mongodb: uri: mongodb://localhost:27017/db_test
- 创建工具类
package com.example.mongodb.utils; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Component; import java.util.List; import javax.annotation.Resource; @Component public class MongoDBUtils<T> { @Resource private MongoTemplate mongoTemplate; /** * 保存数据 * * @param t * @return */ public T save(T t) { return mongoTemplate.save(t); } /** * 查询全部信息 * * @param clazz * @return */ public List<T> find(Class clazz) { return mongoTemplate.findAll(clazz); } /** * 条件查询 * * @param query * @param clazz * @return */ public List<T> find(Query query, Class clazz) { return mongoTemplate.find(query, clazz); } /** * 分页条件查询 * * @param pageNo 当前页码 * @param pageSize 每页显示条目数 * @param query 查询条件 * @param clazz 返回值类型 * @return */ public List<T> page(int pageNo, int pageSize, Query query, Class clazz) { int skip = pageSize * (pageNo - 1); query.skip(skip).limit(pageSize); return this.find(query, clazz); } /** * 查询总数 * * @param query 查询条件 * @param clazz 返回值类型 * @return */ public long query(Query query, Class clazz) { return mongoTemplate.count(query, clazz); } /** * 查询单个值 * * @param query 查询条件 * @param clazz 返回值类型 * @param <T> * @return */ public <T> T findOne(Query query, Class clazz) { return (T) mongoTemplate.findOne(query, clazz); } /** * 查询单个值 * * @param key 键 * @param value 值 * @param clazz 返回值类型 * @param <T> * @return */ public <T> T findOne(String key, Object value, Class clazz) { Query query = Query.query(Criteria.where(key).is(value)); return (T) this.findOne(query, clazz); } /** * 修改单个值 * * @param query 查询条件 * @param update 修改值 * @param clazz 返回值类型 * @return */ public long update(Query query, Update update, Class clazz) { UpdateResult updateResult = mongoTemplate.updateFirst(query, update, clazz); return updateResult.getModifiedCount(); } /** * 修改多个值 * * @param query * @param update * @param clazz * @return */ public long updates(Query query, Update update, Class clazz) { UpdateResult updateResult = mongoTemplate.updateMulti(query, update, clazz); return updateResult.getModifiedCount(); } /** * 删除匹配到的所有数据 * * @param query * @param clazz * @return */ public long remove(Query query, Class clazz) { DeleteResult deleteResult = mongoTemplate.remove(query, clazz); return deleteResult.getDeletedCount(); } }
- 创建测试控制器
package com.example.mongodb.controller; import com.example.mongodb.pojo.User; import com.example.mongodb.utils.MongoDBUtils; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.web.bind.annotation.*; import java.util.List; import javax.annotation.Resource; @RestController public class TestController { @Resource private MongoDBUtils mongoDBUtils; // 插入 @PostMapping("/user/add") public Boolean add(String name, Integer age, String sex) { User usre = new User(name, age, sex); return null != mongoDBUtils.save(usre); } // 单条件查询 @GetMapping("/user/find") public List finds(String name) { Query query = Query.query(Criteria.where("name").is(name)); List<User> users = mongoDBUtils.find(query, User.class); return users; } // 多条件分页查询 @GetMapping("/user/page") public List finds(Integer page, Integer size, String name, String sex) { Criteria criteria = new Criteria(); criteria.and("name").is(name).and("sex").is(sex); Query query = Query.query(criteria); List<User> users = mongoDBUtils.page(page, size, query, User.class); return users; } // 查询单个值 @GetMapping("/getuser") public User findOne(String name) { Query query = Query.query(Criteria.where("name").is(name)); User user = (User) mongoDBUtils.findOne(query, User.class); return user; } // 修改 @PostMapping("/setuser") public boolean set(@RequestBody User user) { Query query = Query.query(Criteria.where("name").is(user.getName())); Update update = new Update(); update.set("age", user.getAge()).set("sex", user.getSex()); return mongoDBUtils.update(query, update, User.class) > 0; } // 删除 @GetMapping("/deluser") public boolean del(String name) { Query query = Query.query(Criteria.where("name").is(name)); return mongoDBUtils.remove(query, User.class) > 0; } }
整合 邮件发送
- 添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
- 项目配置
mail.host=smtp.qq.com mail.username=<邮箱地址:**@**.com> mail.password=<邮箱密码> mail.smtpAuth=true mail.smtpStarttlsEnable=true mail.smtpStarttlsRequired=true mail.defaultEncoding=UTF-8
- 创建配置类
package com.example.mail.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; @Component @PropertySource("classpath:mail.properties") @ConfigurationProperties(prefix = "mail") public class MailConfig { private String host; private String username; private String password; private String smtpAuth; private String smtpStarttlsEnable; private String smtpStarttlsRequired; private String defaultEncoding; // 省略getter/setter }
- 创建工具类
package com.example.mail.utils; import com.example.mail.config.MailConfig; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Properties; @Component public class MailUtils { @Resource private MailConfig mailConfig; /** * 发送邮件 * * @param to 收件人 * @param title 标题 * @param content 正文 * @return */ public boolean sendMail(String to, String title, String content) { try { SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); simpleMailMessage.setFrom(mailConfig.getUsername()); simpleMailMessage.setTo(to); simpleMailMessage.setSubject(title); simpleMailMessage.setText(content); JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); javaMailSender.setUsername(mailConfig.getUsername()); javaMailSender.setHost(mailConfig.getHost()); javaMailSender.setPassword(mailConfig.getPassword()); javaMailSender.setDefaultEncoding(mailConfig.getDefaultEncoding()); Properties properties = new Properties(); properties.setProperty("mail.smtp.auth", mailConfig.getSmtpAuth()); properties.setProperty("mail.smtp.starttls.enable", mailConfig.getSmtpStarttlsEnable()); properties.setProperty("mail.smtp.starttls.required", mailConfig.getSmtpStarttlsRequired()); javaMailSender.setJavaMailProperties(properties); javaMailSender.send(simpleMailMessage); return true; } catch (Exception e) { e.printStackTrace(); return false; } } }
- 创建测试控制器
package com.example.mail.controller; import com.example.mail.utils.MailUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class TestController { @Resource private MailUtils mailUtils; @GetMapping("/") public boolean test() { String to = "**@**.**"; String title = "Test SpringBoot Mail"; String content = "测试内容"; return mailUtils.sendMail(to, title, content); } }
整合 Swagger2
- 添加依赖
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
- 环境配置
swagger.title=swagger测试项目 swagger.description=swagger测试案例 swagger.version=1.0.0
- 创建配置类
package com.example.swagger2.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @PropertySource("classpath:swagger.properties") @ConfigurationProperties("swagger") @EnableSwagger2 public class SwaggerConfig { private String title; private String description; private String version; // 省略Getter/Setter @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()).build(); } public ApiInfo apiInfo() { return new ApiInfoBuilder() .title(this.title) .description(this.description) .version(this.version).build(); } }
- 创建测试控制器
package com.example.swagger2.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Api(tags = "测试类") @RestController @RequestMapping("/test") public class TestController { @ApiOperation("测试方法") @GetMapping("/") public String test( @ApiParam(value = "入参", required = true) @RequestParam String text) { return text; } }
- 查看Swagger接口文档
访问:http://localhost:8080/swagger-ui.html