代驾APP_第一章_项目环境搭建_第一节

代驾APP_第一章_项目环境搭建

文章目录

华夏代驾系统由若干个子系统(服务)组成的,这些子系统都是隶属于hxds根项目的,所以这节课我们把根项目创建出来。上一节

1-1 创建根项目

一、创建SpringBoot项目

根项目是SpringBoot类型的,所以我们按照普通的SpringBoot项目去创建就可以了。

依赖项界面我们什么都不需要勾选,一会儿同意覆盖pom.xml文件即可。图片描述

依赖项界面我们什么都不需要勾选,一会儿同意覆盖pom.xml文件即可。

图片描述

项目创建好之后,把红色标记的文件和文件夹删除。

img

二、覆盖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文件中引用的依赖库。

img

即便Maven报出这些错误提示,你也不用理会,将来我们把子系统创建好就可以了。

img

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文件中引用的依赖库。

图片描述
虽然公共模块不需要主类运行,但是主类还是要保留,因为将来打包需要。要是你把主类删除了,华夏代驾项目整体打包就会出错。

img

三、编写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包里面。

img

微信支付要用到小程序的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-idkey从本课程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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
代驾小程序源码_135k代驾v1.2.24是一套完整的代驾服务小程序源码,包含前端和后端开发部分。 前端开发部分使用了主流的小程序开发框架,如微信小程序框架。开发者可以使用微信开发者工具进行开发调试。前端开发部分主要负责用户端的界面展示和用户交互。开发者需要根据自己的需求进行界面设计和功能开发,并通过与后台服务器的通信来实现数据的获取和更新。 后端开发部分使用了主流的后端开发语言和框架,如Java、Python等。开发者需要搭建相应的开发环境,并根据需求进行后端接口的开发和数据库的设计。后端开发部分主要负责处理用户端的请求和数据,以及与数据库的交互。开发者可以根据需求自行配置后端接口和数据库,并确保后端与前端的数据传输正常。 配置教程会提供详细的步骤和指导,帮助开发者完成源码的配置和部署。配置教程包括以下内容: 1. 前端配置:包括安装微信开发者工具,导入源码,配置小程序的基本信息(如小程序名称、AppID等),以及配置与后端服务器的通信地址。 2. 后端配置:包括配置开发环境,安装相关依赖,导入源码,配置数据库连接信息,以及启动后台服务器。 3. 数据库配置:包括创建数据库,设计表结构,配置数据源和连接信息。 4. 接口配置:根据需求配置前端与后端的接口地址和参数,确保数据传输的正确性和安全性。 配置教程会提供详细的步骤和截图,开发者可以根据教程依次进行配置和操作。同时,如果遇到问题,可以参考配置教程中的常见问题解答部分,或者与开发者社区进行交流和讨论。 总之,代驾小程序源码_135k代驾v1.2.24提供了完整的前端和后端开发部分,配置教程将帮助开发者完成源码的配置和部署。希望以上回答对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

管程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值