第一步:pom.xml的依赖包很重要
用啥依赖啥,下面是常用的
<dependencies>
<!--非关系型数据库Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--数据库Mysql8.0.22-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--小辣椒插件(@Data注解不需要写Getter和Setter方法)-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!--七牛云-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.7.0, 7.7.99]</version>
</dependency>
<!--Email-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--Jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.18.2</version>
</dependency>
<!--支付宝-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.12.4.ALL</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>compile</scope>
</dependency>
</dependencies>
第二步:配置application.properties文件
#端口号
server.port=8082
#数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/medical_care?characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#mybatis
mybatis.mapper-locations=mapper/*.xml
mybatis.type-aliases-package=com.weiyi.pojo
#redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.database=0
#jpa的配置,告诉jpa使用的是那个数据库
spring.jpa.database=mysql
#告诉Jpa是否自动生成表,当字段更新时,会自动更新到数据库
spring.jpa.generate-ddl=false
#是否打印sql语句
spring.jpa.show-sql=true
#邮箱的配置信息
spring.mail.host=smtp.qq.com
#使用哪一个用户
spring.mail.username=2652271195@qq.com
#密码
spring.mail.password=utzqxypczavwecbi
#设置编码格式
spring.mail.default-encoding=utf-8
#七牛云
qiniu.ak=xSoFBF7SFwQUwea_ar58j76VplSv1qSNfe7Fof_Z
qiniu.sk=tPigX3swM4InLTlDX0pOat6laUi5YH5y4v4O-OWp
qiniu.bucket=majiayu
qiniu.url=http://r0tahe0jh.hb-bkt.clouddn.com/
#支付宝
pay.url=https://openapi.alipaydev.com/gateway.do
pay.APP_ID=2021000118624273
pay.APP_PRIVATE_KEY=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsIyRDBel9yhGXOir/pZBTbxVneiaCLLq1isAo59SVvV3jDt1xXB4Q1KvsJQ/SzXhXmeIZlAkslqTGEsizWQtg/zfA7wj14RPK9THxplUp0xhZhX4TQAfNgOtZ8Z517on5T4W4kvTvKGEpnbNkPg7gzu2YG6UpYQCHUOVjpHxsDYLJA4gA6lSf7kSEVgH61fypumak9Tn+kiZFP9EBIZVYteYL9NVnlBcr97d+W21o86Uq+CATu55Vw1N5rX8r8vDz9tg0s/V8EOQP5l2LVcFFK3JehwCgHepfqCmNXmocoRtv5nQOweGcNxOTmiEijRdef47dlYjn5Pv/EeImpsRjAgMBAAECggEAF8c+8hc1+s9YALjjSa84MZ5NqZ6hBShinkNNahkkL48aEgxyoH8mFBMcsKEp/2essQUry3a8kbE5j7b2jHfHb52xuPAMH9L4pfea75OXfhCP84XSNZyJt2SQnjsXNZk+6/aFNUrvlL3SNip3pmhAK+PJxFJFTWL97LNLDKmjGlXFcgzpKNJLCzCp7UoDr5B3Y2yjS6DBJ3UaffrZXm1Npmb4sR9cAsjw3bbiPWm90ZeEPXSwMU8ykhud9DSeHrYNpUvqe0wsnZl4aMbI3/aAGJzAFqiqVrystGjfSDSw8QdWe5kfa5sMONj+u3b/kWpw1m0eCAYiBW0YjURvpWsSWQKBgQDWRpXEnjGzWoDLK8CFPLRIZfJl1MdxEeYlsKUqCLhFCK57rgbf7yOPctOYQ3LORifsWX59Qt7us/eGVQxWPHvo8I2HxRv4UhV/af+opJHp8iDY8HVsf//5aQ2MH4omyWfkvNkrNk7Xmcz34S3M/6LiEoUYbXekwd03jLJ1w3Qj1wKBgQDNqAACvFlzRxN2SxjWw2MVg//qosNaWhJl5d19yjbrmFFqiK8tmRoYLTNks1hI2b6T1N7aRNjX+dklkrpC8RmlxBTMOwjntRtgD19SY2dJKwhROZBDhaJh7mMV+b/B4G9+KNcwOR5LiEao2OrCIDMvs5cGSKLaSsKSabEXq8RSVQKBgBLSnoNoFhuYPqoaTM4nd/rIIdP6Lg7rsJjs/IVFwNInohQxRF9VhX0rbBT7D9G47fbgIbFlN2ommv7M58mHhKcAwp4DnaJhq4vGxvOMiVjQsTv9W4NNdzH0nYEKoDsqBBtez4DxQ1nDI/M+b6SLbEaJs/FiZFkvwnwHuwGHSuN/AoGABdFg3rLxXN9/33LUaw7v+KXZUYv1NtMhfhx4nZxg3V1bwEXJnuKb6F8u+wRP1Q/D4m69NzOHZuS8jeGOv2IOta/MXtK0t8lZ0ufcbHo/a8R54cJdIGvhYh/aUb7U++kbflgtbkHPZ5edWB161q8Og6Ty+syHPuGqi3XN+rtzPFkCgYEA1TCB2eb69YSUTUJGp71e7xVRH1qGYH7Wf8zCCpZOAaZlSFz50rCAgUhFZnwqPzG76wQiZAvYJqbuxmMGt0xqZJIY0p0+bllrLfCmTXzzUJBphBEdrZxnleuPwDVoy6zrCxnbr9lz7mv6TrRPZTjwAY9cjGpMd7BQIDTjj02+xqY=
pay.ALIPAY_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgpV79ScFFeJBPvmCKKATLK8uVgMh1JCePt/E71cKdDl1ks/nN2+vsB4c5CJA5AaZ4esfyi5Ielo4tAdgT6SBPn4fCpBeMJpaZEARGdPIXjb93bA8vgTrCUcH7IeE8n1iLnnOK3dOn81JTc3a3liqdCQ0wUAq2/dhjA41bSXB+RgTCU5tad3vIFkxSDXbPsGx9AOCmCZ1NlB3NNdXs1SvZ4uGMaZCGFcKdN8OIJHVDOf+705qob0JaZK1biWvefH5HJSvW1i8qLTPOQu3LNPb+Hs9jtPp4FzeXhKI1WBiGY4sGyyeqirBjIIY4mD0D/qPv3m/G0hVwVzGWAX2Z6IYpwIDAQAB
pay.FORMAT=json
pay.CHARSET=utf-8
pay.SIGN_TYPE=RSA2
第三步: Redis的配置(config包下)
RedisConfig.java
package com.weiyi.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//使用fastjson序列化
Jackson2JsonRedisSerializer fastJsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
第四步:一些工具类
一.ConversionUtils
package com.weiyi.utils;
import com.alibaba.fastjson.JSONObject;
import com.weiyi.pojo.McUser;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class ConversionUtils {
@Resource
private RedisTemplate<String, Object> redisTemplate;
public McUser getUserByToken(String token) {
//2.判断在redis是否有该用户信息
Boolean flag = redisTemplate.hasKey(token);
if (Boolean.FALSE.equals(flag)) {
return null;
}
//通过json转换为User对象
Object o = redisTemplate.opsForValue().get(token);
return JSONObject.parseObject(JSONObject.toJSONString(o), McUser.class);
}
}
二.Email
package com.weiyi.utils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Random;
@Component
public class Email {
@Resource
MailSender mailSender;
@Value("${spring.mail.username}")
private String from;
public String sendEmail(String email) {
//1.声明发送的对象
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
//设置收件人
simpleMailMessage.setTo(email);
//设置发件人
simpleMailMessage.setFrom(from);
//设置主题
simpleMailMessage.setSubject("微医注册验证码");
//设置邮件内容
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 4; i++) {
int x = new Random().nextInt(10);
stringBuilder.append(x);
}
simpleMailMessage.setText(stringBuilder.toString());
System.out.println(stringBuilder);
mailSender.send(simpleMailMessage);
return stringBuilder.toString();
}
}
三.订单号生成计数器 GenerateOrderNum
package com.weiyi.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by mrt on 2018/3/27.
*/
public class GenerateOrderNum {
/**
* 锁对象,可以为任意对象
*/
private static final Object lockObj = "lockerOrder";
/**
* 订单号生成计数器
*/
private static long orderNumCount = 0L;
/**
* 每毫秒生成订单号数量最大值
*/
private static final int maxPerMSECSize = 1000;
/**
* 生成非重复订单号,理论上限1毫秒1000个,可扩展
*
* @param tname 测试用
*/
public static synchronized String generate(String tname) {
// 最终生成的订单号
String finOrderNum = "";
try {
synchronized (lockObj) {
// 取系统当前时间作为订单号变量前半部分,精确到毫秒
long nowLong = Long.parseLong(new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()));
// 计数器到最大值归零,可扩展更大,目前1毫秒处理峰值1000个,1秒100万
if (orderNumCount >= maxPerMSECSize) {
orderNumCount = 0L;
}
//组装订单号
String countStr = maxPerMSECSize + orderNumCount + "";
finOrderNum = nowLong + countStr.substring(1);
orderNumCount++;
System.out.println(finOrderNum + "--" + Thread.currentThread().getName() + "::" + tname);
// Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
return finOrderNum;
}
public static void main(String[] args) {
// 测试多线程调用订单号生成工具
/*try {
for (int i = 0; i < 200; i++) {
Thread t1 = new Thread(new Runnable() {
public void run() {
GenerateOrderNum generateOrderNum = new GenerateOrderNum();
generateOrderNum.generate("a");
}
}, "at" + i);
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
GenerateOrderNum generateOrderNum = new GenerateOrderNum();
generateOrderNum.generate("b");
}
}, "bt" + i);
t2.start();
}
} catch (Exception e) {
e.printStackTrace();
}*/
System.out.println(System.currentTimeMillis());
}
}
四.JwtUtils
package com.weiyi.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtUtils {
public String createToken(Map<String, Integer> user) {
//设置算法以及签名
Algorithm algorithmHS = Algorithm.HMAC256("secret");
//设置头部
Map<String, Object> map = new HashMap<>();
map.put("typ", "JWT");
map.put("alg", "HS256");
return JWT.create().withHeader(map)
//签发人
.withIssuer("auth0")
//主题
.withSubject("login")
//受众
.withAudience("users")
//自定义载荷
.withClaim("userid", user.get("userid"))
.sign(algorithmHS);
}
public Map<Object, Object> verfiyToken(String token) {
Map<Object, Object> map = new HashMap<>();
Algorithm algorithmHS = Algorithm.HMAC256("secret");
JWTVerifier verifier = JWT.require(algorithmHS)
.withIssuer("auth0")
.build(); //Reusable verifier instance
try {
DecodedJWT jwt = verifier.verify(token);
map.put("status", true);
map.put("userid", jwt.getClaim("userid").asInt());
return map;
} catch (Exception e) {
map.put("status", false);
return map;
}
}
}
五.图片文件上传 UpLoad
package com.weiyi.utils;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
@Component
public class UpLoad {
@Value("${qiniu.ak}")
private String ak;
@Value("${qiniu.sk}")
private String sk;
@Value("${qiniu.bucket}")
private String bucket;
@Value("${qiniu.url}")
private String url;
public String upload(MultipartFile multipartFile) {
//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region1());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
Auth auth = Auth.create(ak, sk);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(multipartFile.getInputStream(), key, upToken, null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
return url + putRet.hash;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
六.拦截器 Interceptor
package com.weiyi.Interceptor;
import com.alibaba.fastjson.JSON;
import com.weiyi.pojo.resp.BaseResp;
import com.weiyi.utils.JwtUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Map;
@Component
public class Interceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
if (token == null || token.equals("")) {
//拦截请求
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
BaseResp baseResp = new BaseResp(1, "未登录", null, null);
writer.write(JSON.toJSONString(baseResp));
return false;
}
JwtUtils jwtUtils = new JwtUtils();
Map<Object, Object> map = jwtUtils.verfiyToken(token);
if (!(Boolean) map.get("status")) {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
BaseResp baseResp = new BaseResp(1, "token解析异常", null, null);
writer.write(JSON.toJSONString(baseResp));
return false;
}
return true;
}
}