代驾APP_第一章_项目环境搭建
文章目录
华夏代驾系统由若干个子系统(服务)组成的,这些子系统都是隶属于hxds
根项目的,所以这节课我们把根项目创建出来。上一节
1-1 创建根项目
一、创建SpringBoot项目
根项目是SpringBoot类型的,所以我们按照普通的SpringBoot项目去创建就可以了。
依赖项界面我们什么都不需要勾选,一会儿同意覆盖pom.xml
文件即可。
依赖项界面我们什么都不需要勾选,一会儿同意覆盖pom.xml
文件即可。
项目创建好之后,把红色标记的文件和文件夹删除。
二、覆盖pom.xml文件
然后把pom.xml
文件的内容覆盖成下面的样子。另外,本课程已经剔除了有巨大安全漏洞的Log4j版本,所以大家可以放心使用这些依赖。
<?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>
<groupId>com.example</groupId>
<artifactId>hxds</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hxds</name>
<description>hxds</description>
<modules>
<module>common</module>
<module>hxds-dr</module>
<module>hxds-cst</module>
<module>hxds-odr</module>
<module>hxds-snm</module>
<module>hxds-mps</module>
<module>hxds-tm</module>
<module>hxds-mis-api</module>
<module>hxds-oes</module>
<module>hxds-vhr</module>
<module>bff-driver</module>
<module>bff-customer</module>
<module>gateway</module>
</modules>
<packaging>pom</packaging>
<properties>
<java.version>15</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>15</source>
<target>15</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
因为暂时我们没有创建华夏代驾项目的若干子系统,所以pom.xml
文件报错也不用理会,等我们把所有子系统创建出来,根项目就不报错了。
覆盖好pom.xml
文件之后,在pom.xml
文件中任意位置点击鼠标右键,然后选择“Maven”->“重新加载项目”,这样Maven才会引用你pom.xml
文件中引用的依赖库。
即便Maven报出这些错误提示,你也不用理会,将来我们把子系统创建好就可以了。
1-2 创建根项目
在华夏代驾项目中有很多代码属于公共程序,供各个模块调用,所以我们可以把这些代码和配置抽象成公共模块,让其他子系统来引用。
一、创建公共模块
我们在根项目上面点击鼠标右键,然后选择“新建”->“模块”
新建的子系统叫做common
,也是SpringBoot类型的项目。
依赖项目界面依然什么都不需要勾选,我们一会儿覆盖pom.xml
文件即可。
二、配置pom.xml文件
把pom.xml
文件覆盖成下面的样子:
<?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>
<groupId>com.example</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>common</name>
<description>common</description>
<parent>
<artifactId>hxds</artifactId>
<groupId>com.example</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<properties>
<java.version>15</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--腾讯云存储-->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.45</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!--腾讯云-->
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<version>3.1.416</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>15</source>
<target>15</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
</project>
覆盖好pom.xml
文件之后,在pom.xml
文件中任意位置点击鼠标右键,然后选择“Maven”->“重新加载项目”,这样Maven才会引用你pom.xml
文件中引用的依赖库。
虽然公共模块不需要主类运行,但是主类还是要保留,因为将来打包需要。要是你把主类删除了,华夏代驾项目整体打包就会出错。
三、编写YML配置文件
删除resources
目录下的application.properties
文件,然后在这个目录下面创建YML文件,配置文件叫做application-common.yml
,然后编写文件的内容。其中的tencent属性下面的配置可以暂时先不用改,在第三章讲到开通腾讯云对象存储服务的时候你再配置tencent属性的内容也来得及。
spring:
profiles: common
tencent:
cloud:
appId: 腾讯云APPID
secretId: 腾讯云SecretId
secretKey: 腾讯云SecretKey
region-public: 公有存储桶所在地域
bucket-public: 公有存储桶名称
region-private: 私有存储桶所在地域
bucket-private: 私有存储桶名称
wx:
app-id: 你的小程序APPID
app-secret: 你的小程序密钥
mch-id: 商户号ID(课程QQ群共享里能找到)
key: 商户密钥(课程QQ群共享里能找到)
cert-path: 数字证书文件路径(课程QQ群共享里能找到)
minio:
endpoint: http://localhost:9000
access-key: root
secret-key: abc123456
这个YML文件的别名叫做common
,将来可以被引用到其他子系统的YML文件里面。
四、配置XSS过滤器
1. XSS攻击的危害
作为Web网站来说,抵御XSS攻击是必须要做的事情。XSS攻击的手段很简单,就是通过各种手段向我们的Web网站植入JS代码。比如说普通网站的用户注册、论坛网站的发帖和回帖,以及电商网站的商品评价等等,黑客在文本框中填写的文字信息里面包含一段JS代码,那么前端页面在显示这个信息的时候,就会执行这些JS代码了。例如我在慕课网上面回复某个问题的时候,填写的内容如下:
如果慕课网没有对保存的信息做XSS转义处理的话,将来某个用户打开网页,恰好翻到我的回复。这时候<script>
标签就会被当做JS脚本来执行了,于是用户的浏览器就会弹出HelloWorld这样的文字。其实弹出HelloWorld已经是危害很轻的XSS攻击了,如果黑客植入的JS脚本先读取浏览器的Cookie信息,然后把Cookie通过Ajax发送给黑客的服务器,那么远端的黑客就能用你的Cookie来模拟登陆,这多可怕啊。
防御XSS攻击的办法很简单,那就是对所有用户的数据先做转义处理,然后再保存到数据库里面。转义之后的信息,将来被加载到网页上面就丧失了作为脚本执行的能力。比如说上面文本框里面的脚本,经过转义之后就变成了<script>alert("HelloWorld")</script>
这个样子。就拿<script>
来说吧,它会被渲染成<script>
字符串,而不是当做脚本标签来执行。
2. 用过滤器对XSS脚本转义
首先我们要创建一个执行转义的封装类,这个类继承HttpServletRequestWrapper
父类。在Web项目中,我们无法修改HttpServletRequest
实现类的内容,因为请求的实现类是由各个Web容器厂商自己扩展的。但是有时候我们还想修改请求类中的内容,这该怎么办呢?Java语言给我们留出了缺口,我们只要继承Java Web内置的HttpServletRequestWrapper
父类,就能修改请求类的内容。如果我们能修改请求类的内容,我要修改获取请求数据的函数,返回的并不是客户端Form表单或者Ajax提交的数据,而是经过转义之后数据。
在com.example.hxds.common.config.xss
包中创建XssHttpServletRequestWrapper.java
类。把获取请求头和请求体数据的方法都要重写,返回的是经过XSS转义后的数据。
package com.example.hxds.common.config.xss;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.Map;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value= super.getParameter(name);
if(!StrUtil.hasEmpty(value)){
value=HtmlUtil.cleanHtmlTag(value);
}
return value;
}
@Override
public String[] getParameterValues(String name) {
String[] values= super.getParameterValues(name);
if(values!=null){
for (int i=0;i<values.length;i++){
String value=values[i];
if(!StrUtil.hasEmpty(value)){
value=HtmlUtil.cleanHtmlTag(value);
}
values[i]=value;
}
}
return values;
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> parameters = super.getParameterMap();
LinkedHashMap<String, String[]> map=new LinkedHashMap();
if(parameters!=null){
for (String key:parameters.keySet()){
String[] values=parameters.get(key);
for (int i = 0; i < values.length; i++) {
String value = values[i];
if (!StrUtil.hasEmpty(value)) {
value = HtmlUtil.cleanHtmlTag(value);
}
values[i] = value;
}
map.put(key,values);
}
}
return map;
}
@Override
public String getHeader(String name) {
String value= super.getHeader(name);
if (!StrUtil.hasEmpty(value)) {
value = HtmlUtil.cleanHtmlTag(value);
}
return value;
}
@Override
public ServletInputStream getInputStream() throws IOException {
InputStream in= super.getInputStream();
InputStreamReader reader=new InputStreamReader(in, Charset.forName("UTF-8"));
BufferedReader buffer=new BufferedReader(reader);
StringBuffer body=new StringBuffer();
String line=buffer.readLine();
while(line!=null){
body.append(line);
line=buffer.readLine();
}
buffer.close();
reader.close();
in.close();
Map<String,Object> map=JSONUtil.parseObj(body.toString());
Map<String,Object> result=new LinkedHashMap<>();
for(String key:map.keySet()){
Object val=map.get(key);
if(val instanceof String){
if(!StrUtil.hasEmpty(val.toString())){
result.put(key,HtmlUtil.cleanHtmlTag(val.toString()));
}
}
else {
result.put(key,val);
}
}
String json=JSONUtil.toJsonStr(result);
ByteArrayInputStream bain=new ByteArrayInputStream(json.getBytes());
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bain.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}
接下来我们要创建一个Filter类,拦截所有HTTP请求,然后调用上面创建的XssHttpServletRequestWrapper
类,这样就能按照我们设定的方式获取请求中的数据了。
在com.example.hxds.common.config.xss
包中创建XssFilter.java
类。
package com.example.hxds.common.config.xss;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
XssHttpServletRequestWrapper wrapper = new XssHttpServletRequestWrapper(request);
filterChain.doFilter(wrapper, servletResponse);
}
@Override
public void destroy() {
}
}
五、允许跨域请求
允许跨域请求是一个很重要的设置,如果不设置,那么移动端小程序和Web管理页面都无法访问后端Java程序。SpringBoot项目中允许跨域请求比较简单,只需要我们定义好配置类即可。
在com.example.hxds.common.config
包中创建CorsConfig.java
类,然后设置允许跨域请求。
package com.example.hxds.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
.maxAge(3600);
}
}
六、定义分页封装类
在本项目中有很多模块都用到了数据分页显示,为了把分页用到的数据封装存储起来,我们需要创建一个封装类。在com.example.hxds.common.util
包里面创建PageUtils.java
类。
package com.example.hxds.common.util;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class PageUtils implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总记录数
*/
private long totalCount;
/**
* 每页记录数
*/
private int pageSize;
/**
* 总页数
*/
private int totalPage;
/**
* 当前页数
*/
private int pageIndex;
/**
* 列表数据
*/
private List list;
public PageUtils(List list, long totalCount, int pageIndex, int pageSize) {
this.list = list;
this.totalCount = totalCount;
this.pageSize = pageSize;
this.pageIndex = pageIndex;
this.totalPage = (int) Math.ceil((double) totalCount / pageSize);
}
}
七、自定义异常类
在开发项目的过程中,很多人都喜欢自定义异常,处理异常的时候可以根据异常的类型,判断出哪些是Java语言异常,哪些是业务异常。在本项目中,我们也是需要自定义异常类的。
在com.example.hxds.common.exception
包中创建HxdsException.java
类。这个异常类里面封装了两样东西:异常消息和状态码。
package com.example.hxds.common.exception;
import lombok.Data;
@Data
public class HxdsException extends RuntimeException {
private String msg;
private int code = 500;
public HxdsException(String msg) {
super(msg);
this.msg = msg;
}
public HxdsException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public HxdsException(String msg, int code) {
super(msg);
this.msg = msg;
this.code = code;
}
public HxdsException(String msg, int code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
}
八、封装全局Web方法返回对象
微服务体系中,服务返回的响应理当有统一的格式。比如说,哪个属性是状态码,哪个属性是消息内容,哪个属性是业务数据等等。如果我们能定义一个Java类,里面设置好相应的变量。将来Web方法返回的数据封装在这个封装类,然后Spring框架把数据转换成JSON格式,那么客户端得到的响应内容格式非常的统一。
我在com.example.hxds.common.util
包里面创建R
类,里面有相应的变量保存状态码和业务消息。
package com.example.hxds.common.util;
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
public class R extends HashMap<String, Object> {
public R() {
put("code", HttpStatus.SC_OK);
put("msg", "success");
}
@Override
public R put(String key, Object value) {
super.put(key, value);
return this;
}
public static R ok() {
return new R();
}
public static R ok(String msg) {
R r = new R();
r.put("msg", msg);
return r;
}
public static R ok(Map<String, Object> map) {
R r = new R();
r.putAll(map);
return r;
}
public static R error(int code, String msg) {
R r = new R();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static R error(String msg) {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
}
public static R error() {
return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
}
}
九、微信支付工具类
因为华夏代驾小程序包含了微信支付功能,例如代驾客户支付车费,司机缴纳违规罚款、钱包充值等等,所以我们要把微信支付提供的API接口类放入到项目中。我已经把这些支付相关的工具类放入了com.example.hxds.common.wxpay
包里面。
微信支付要用到小程序的APPID、密钥、商户号和数字证书等,所以你要打开application-common.yml
文件,填写上相关信息。
spring:
profiles: common
minio:
endpoint: http://192.168.99.106:9000
access-key: root
secret-key: abc123456
wx:
app-id: 小程序的APPID
app-secret: 小程序的密钥
mch-id: 商户号(看课程QQ群共享文档)
key: 商户密钥(看课程QQ群共享文档)
cert-path: 数字证书文件路径(看课程QQ群共享文档)
小程序的APPID和密钥先暂时填写你自己的,等到用到支付功能的时候,再替换上课程提供的小程序APPID和密钥。mch-id
和key
从本课程QQ群共享文档中得到,包括数字证书也是从QQ群共享中下载。cert-path
配置的是数字证书在你本地的路径。
十、封装微信工具类
我们在实现用微信登陆华夏代驾小程序的的时候,需要调用微信服务器的API,拿到OpenId
永久授权字符串。所以我们要把调用微信服务器API的常用操作封装起来,在项目中使用起来更加的简单。
在com.example.hxds.common.util
包中创建MicroAppUtil.java
类。
package com.example.hxds.common.util;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.hxds.common.exception.HxdsException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Component("MicroAppUtil")
public class MicroAppUtil {
@Value("${wx.app-id}")
private String appId;
@Value("${wx.app-secret}")
private String appSecret;
public String getOpenId(String code) {
String url = "https://api.weixin.qq.com/sns/jscode2session";
HashMap map = new HashMap();
map.put("appid", appId);
map.put("secret", appSecret);
map.put("js_code", code);
map.put("grant_type", "authorization_code");
String response = HttpUtil.post(url, map);
JSONObject json = JSONUtil.parseObj(response);
String openId = json.getStr("openid");
if (openId == null || openId.length() == 0) {
throw new RuntimeException("临时登陆凭证错误");
}
return openId;
}
public String getAccessToken() {
String url = "https://api.weixin.qq.com/cgi-bin/token";
HashMap map = new HashMap() {
{
put("grant_type", "client_credential");
put("appid", appId);
put("secret", appSecret);
}};
String response = HttpUtil.get(url, map);
JSONObject json = JSONUtil.parseObj(response);
if (json.containsKey("access_token")) {
String accessToken = json.getStr("access_token");
return accessToken;
} else {
throw new HxdsException(json.getStr("errmsg"));
}
}
}
十一、定义JSON转换类
因为本课程数据表的主键生成方式我采用了雪花算法,所以主键字段都是bigint
类型的,映射到Java中就是long类型。前端JavaScript语言并不支持long类型,所有long类型数据都会出现自动截断。所以我们要把返回给移动端或者前端的long类型数据转换成字符串格式。因为移动端和前端页面也不需要做数学运算,基本上就是把数据显示在页面上面,所以我们返回字符串格式的长整型数据,一点问题都没有。
SpringBoot项目中的Controller类加上@RestController
注解之后,Web方法返回的对象会自动被转换成JSON格式的。这时候我们定义一个Java类,加上@JsonComponent
注解,就能控制返回数据的类型类。
在com.example.hxds.common.config
包中创建JsonSerializerManage.java
类,然后写入下面的代码。
package com.example.hxds.common.config;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* 把Long类型和浮点类型数据转换成字符串,返回前端的时候避免丢失精度
*/
@JsonComponent
public class JsonSerializerManage {
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
//忽略value为null 时 key的输出
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
SimpleModule module = new SimpleModule();
//长整型和浮点型在JavaScript上面都会丢失精度,所以要转换成字符串类型
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(Long.TYPE, ToStringSerializer.instance);
module.addSerializer(Double.class, ToStringSerializer.instance);
module.addSerializer(Double.TYPE, ToStringSerializer.instance);
module.addSerializer(Float.class, ToStringSerializer.instance);
module.addSerializer(Float.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(module);
return objectMapper;
}
}
十二、封装腾讯云对象存储服务
我们需要用腾讯云对象存储服务保存文件,例如司机的身份证和驾驶证照片,这里我们先创建操作腾讯云对象存储服务的封装类,第三章会讲到这个类的用途和原理,这里不展开说明了。
在com.example.hxds.common.util
包中创建CosUtil.java
代码,然后写入下面的代码:
package com.example.hxds.common.util;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.example.hxds.common.exception.HxdsException;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.model.ciModel.auditing.ImageAuditingRequest;
import com.qcloud.cos.model.ciModel.auditing.ImageAuditingResponse;
import com.qcloud.cos.region.Region;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URL;
import java.util.*;
@Component
public class CosUtil {
@Value("${tencent.cloud.appId}")
private String appId;
@Value("${tencent.cloud.secretId}")
private String secretId;
@Value("${tencent.cloud.secretKey}")
private String secretKey