微服务-官网module

1.pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.hcnet2006.blog</groupId>
        <artifactId>blog-base</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>cn.hcnet2006.blog</groupId>
    <artifactId>hcnet-website</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hcnet-website</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot-admin.version>2.2.2</spring-boot-admin.version>
        <docker.image.prefix>47.97.170.173:5000</docker.image.prefix>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--OAuth2-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <!--JSON WEB TOKEN-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
        <!--添加MyBatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <!--添加MyBatis生成器-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <!--MyBatis分页查询-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.13</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.19</version>
        </dependency>
        <!--集成druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>${spring-boot-admin.version}</version>

        </dependency>
        <!--APK解析-->
        <dependency>
            <groupId>net.dongliu</groupId>
            <artifactId>apk-parser</artifactId>
            <version>2.6.10</version>
        </dependency>
        <!--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>
        <!--添加消息总线依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <!--fastjson依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <!--使用googlezxing生成二维码-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.2.0</version>
        </dependency>
        <!--转换MARKDOWN-->
        <dependency>
            <groupId>org.pegdown</groupId>
            <artifactId>pegdown</artifactId>
            <version>1.6.0</version>
        </dependency>
        <!--JavaCV-->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>4.0.2-1.4.3</version>
        </dependency>
        <!--集成阿里云OSS存储对象服务-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--防止jks密钥文件被编译,导致乱码-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>cert</nonFilteredFileExtension>
                        <nonFilteredFileExtension>jks</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>
            <!--使用Maven和Dockerfile命令构建镜像-->
            <plugin>

                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!--生成镜像名称-->
                    <repository>
                        ${docker.image.prefix}/${project.name}
                    </repository>
                    <!--生成镜像版本-->
                    <tag>${project.version}</tag>
                    <!--推送到私有仓库或者DockerHub时需要开启用户认证-->
                    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                        <JAR_EXPOSE>8204</JAR_EXPOSE>
                    </buildArgs>

                    <!--                    <imageName>${project.name}:${project.version}</imageName>-->
                    <!--                    <baseImage>java</baseImage>-->
                    <!--                    <entryPoint>-->
                    <!--                        {"java","-jar","/${project.build.finalName}.jar"}-->
                    <!--                    </entryPoint>-->
                    <!--                    &lt;!&ndash;                    <dockerDirectory>&ndash;&gt;-->
                    <!--                    &lt;!&ndash;                        ${project.basedir}/src/main/docker&ndash;&gt;-->
                    <!--                    &lt;!&ndash;                    </dockerDirectory>&ndash;&gt;-->
                    <!--                    <skipDockerBuild>false</skipDockerBuild>-->
                    <!--                    <resources>-->
                    <!--                        <resource>-->
                    <!--                            <directory>${project.build.directory}</directory>-->
                    <!--                            <include>${project.build.finalName}.jar</include>-->
                    <!--                        </resource>-->
                    <!--                    </resources>-->
                </configuration>
                <!--直接使用 mvn install 命令打包项目, 就会自动构建并推送镜像-->
                <executions>
                    <execution>
                        <id>default</id>
                        <phase>install</phase>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2.application.yml

server:
  port: 8210
spring:
  application:
    name: hcnet-website
#  cloud:
#    consul:
#      host: localhost
#      port: 8500
#      discovery:
#        service-name: ${spring.application.name}
  servlet:
    multipart:
      enabled: true
      file-size-threshold: 0
      max-file-size: 100000000
      max-request-size: 100000000
      resolve-lazily: false
  boot:
    admin:
      client:
        url: "http://172.17.0.1:8205"
        instance:
          service-base-url: "http://172.17.0.1:8205"
  datasource:
    name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://172.17.0.1:3306/hc_official_website?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
      filters: stat, wall, config
      initial-size: 1
      max-active: 100
      max-wait: 60000
      min-idle: 1
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: select 'x'
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 50
      max-pool-prepared-statement-per-connection-size: 20
      username: root
      password: 123456
  rabbitmq:
    username: guest
    password: guest
    port: 5672
    publisher-confirms: true
    virtual-host: /
    host: 172.17.0.1
management:
  endpoint:
    health:
      show-details: always
  endpoints:
    web:
      exposure:
        include: '*'
mybatis:
  mapper-locations: classpath:/mappers/*Mapper.xml
feign:
  hystrix:
    enabled: true

3.bootstrap.yml

spring:
  application:
    name: hcnet-website
  cloud:
    config:
      discovery:
        service-id: config-server #配置中心
        enabled: true #开启发现服务
      name: user-server
      profile: pro #对应{profiles}部分
      label: master
    consul:
      host: 172.17.0.1
      port: 8500
      discovery:
        service-name: ${spring.application.name}
        hostname: 172.17.0.1
        health-check-url: http://172.17.0.1:8210/actuator/health
  zipkin:
    base-url: http://172.17.0.1:9411/
    sleuth:
      sampler:
        probability: 1

feign:
  hystrix:
    enabled: true

4.配置MYBATI代码生成器

4.1.java代码部分

public class Generator {
    public static void main(String []args) throws Exception{
        //MBG执行过程中的警告信息
        List<String> warnings = new ArrayList<>();
        //当前代码重复时,覆盖旧的代码
        boolean overwrite = true;
        //读取BMG配置文件
        InputStream is = Generator.class.getResourceAsStream(
                "/generator/generatorConfig.xml");
        //配置解析器
        ConfigurationParser cp = new ConfigurationParser(warnings);
        //配置器
        Configuration config = cp.parseConfiguration(is);
        //关闭输入流
        is.close();
        //默认回滚
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        //创建MBG
        MyBatisGenerator mbg = new MyBatisGenerator(config,callback,warnings);
        //执行生成代码
        mbg.generate(null);
        //输出警告信息
        for(String warn: warnings){
            System.out.println(warn);
        }
    }

}

4.2 XML配置部分

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--1. context属性targetRuntime设置为MyBatis3Simple避免生成Example相关的代码和方法,
    如果需要Example设置为MyBatis3
        2. context属性defaultModelType设为flat,目的是使每张表只生成一个实体类
        3. 因为此处使用的数据库为MySql,所以前后分隔符都设置为‘‘’
        4. 注释生成器commentGenerator中配置了生成数据库的注释信息,并且禁止在注释中生成日期
        5. jdbcConnection简单的配置了要链接的数据源信息
        6. javaModelGenerator配置生成的包名为com.hcnet2006.mango,
        targetProject设置为src\main\java
        7. sqlMapGenerator配置生成的Mapper.xml文件位置,这里采用XMLMapper类型。接口和XML完全分离
        8. javaClientGenerator配置生成Mapper接口的位置,这里采用的XMLMAPPER类型,接口和XML完全分离
        9. 最后的table使用通配符匹配数据库中所有的表,所有表都有主键自赠的id字段,
        sqlStatement针对当前数据库配置MYSQL
            -->

<context id="MySqlTables"
         targetRuntime="MyBatis3Simple"
         defaultModelType="flat">
    <!--关键字与分隔符加反引号-->
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
    <!--序列化以及字符串插件-->
    <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
    <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
    <!--注释生成器-->
    <commentGenerator>
        <!--是否阻止生成注释-->
        <property name="suppressAllComments" value="true"/>
        <!--是否生成带注释的时间戳-->
        <property name="suppressDate" value="true"/>
        <!--是否添加数据表的备注信息-->
        <property name="addRemarkComments" value="true"/>
    </commentGenerator>
    <!--JDBC数据源连接-->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/hc_official_website?serverTimezone=UTC"
                    userId="root"
                    password="123456"
    />
    <!--实体类代码生成器-->
    <javaModelGenerator targetPackage="cn.hcnet2006.blog.hcnetwebsite.bean" targetProject="./upload-apk/src/main/java">
        <!--            <property name="trimStrings" value="true"/>-->
    </javaModelGenerator>
    <!--MapperXML文件生成器-->
    <sqlMapGenerator targetPackage="mappers" targetProject="./upload-apk/src/main/resources"/>
    <!--Mappper接口生成器-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="cn.hcnet2006.blog.hcnetwebsite.mapper" targetProject="./upload-apk/src/main/java"/>
    <!--数据库表配置-->
    <table tableName="sys_apk">
        <!--数据库主键生成策略-->
        <generatedKey column="id" sqlStatement="Mysql"/>
    </table>
</context>
</generatorConfiguration>

4.3. 解决不同数据库表名相同导致生成覆盖问题

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--1. context属性targetRuntime设置为MyBatis3Simple避免生成Example相关的代码和方法,
    如果需要Example设置为MyBatis3
        2. context属性defaultModelType设为flat,目的是使每张表只生成一个实体类
        3. 因为此处使用的数据库为MySql,所以前后分隔符都设置为‘‘’
        4. 注释生成器commentGenerator中配置了生成数据库的注释信息,并且禁止在注释中生成日期
        5. jdbcConnection简单的配置了要链接的数据源信息
        6. javaModelGenerator配置生成的包名为com.hcnet2006.mango,
        targetProject设置为src\main\java
        7. sqlMapGenerator配置生成的Mapper.xml文件位置,这里采用XMLMapper类型。接口和XML完全分离
        8. javaClientGenerator配置生成Mapper接口的位置,这里采用的XMLMAPPER类型,接口和XML完全分离
        9. 最后的table使用通配符匹配数据库中所有的表,所有表都有主键自赠的id字段,
        sqlStatement针对当前数据库配置MYSQL
            -->

    <context id="MySqlTables"
             targetRuntime="MyBatis3Simple"
             defaultModelType="flat">
        <!--关键字与分隔符加反引号-->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!--序列化以及字符串插件-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--注释生成器-->
        <commentGenerator>
            <!--是否阻止生成注释-->
            <property name="suppressAllComments" value="true"/>
            <!--是否生成带注释的时间戳-->
            <property name="suppressDate" value="true"/>
            <!--是否添加数据表的备注信息-->
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>
        <!--JDBC数据源连接-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/hc_official_website_1?serverTimezone=UTC"
                        userId="root"
                        password="123456"


        >
            <!--确定一个数据库-->
            <property name="nullCatalogMeansCurrent" value="true"/>

        </jdbcConnection>
        <!--实体类代码生成器-->
        <javaModelGenerator targetPackage="cn.hcnet2006.blog.hcnetwebsite.bean" targetProject="./hcnet-website-1/src/main/java">
            <!--            <property name="trimStrings" value="true"/>-->
        </javaModelGenerator>
        <!--MapperXML文件生成器-->
        <sqlMapGenerator targetPackage="mappers" targetProject="./hcnet-website-1/src/main/resources"/>
        <!--Mappper接口生成器-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="cn.hcnet2006.blog.hcnetwebsite.mapper" targetProject="./hcnet-website-1/src/main/java"/>
        <!--数据库表配置-->

        <table tableName="sys_user">
            <!--数据库主键生成策略-->
            <generatedKey column="id" sqlStatement="Mysql"/>
        </table>
    </context>
</generatorConfiguration>

5.设置全局DataBase

全局图片设置

6.HTTP结果封装

6.1.http返回结果封装

package cn.hcnet2006.blog.hcnetwebsite.http;

/**
 * HTTP结果封装
 * @author Louis
 * @date Jan 12, 2019
 */
public class HttpResult {

    private int code = 200;
    private String msg;
    private Object data;

    public static HttpResult error() {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");
    }

    public static HttpResult error(String msg) {
        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);
    }

    public static HttpResult error(int code, String msg) {
        HttpResult r = new HttpResult();
        r.setCode(code);
        r.setMsg(msg);
        return r;
    }

    public static HttpResult ok(String msg) {
        HttpResult r = new HttpResult();
        r.setMsg(msg);
        return r;
    }

    public static HttpResult ok(Object data) {
        HttpResult r = new HttpResult();
        r.setData(data);
        return r;
    }

    public static HttpResult ok() {
        return new HttpResult();
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

}

6.2.Http状态封装


public interface HttpStatus {

    // --- 1xx Informational ---

    /** {@code 100 Continue} (HTTP/1.1 - RFC 2616) */
    public static final int SC_CONTINUE = 100;
    /** {@code 101 Switching Protocols} (HTTP/1.1 - RFC 2616)*/
    public static final int SC_SWITCHING_PROTOCOLS = 101;
    /** {@code 102 Processing} (WebDAV - RFC 2518) */
    public static final int SC_PROCESSING = 102;

    // --- 2xx Success ---

    /** {@code 200 OK} (HTTP/1.0 - RFC 1945) */
    public static final int SC_OK = 200;
    /** {@code 201 Created} (HTTP/1.0 - RFC 1945) */
    public static final int SC_CREATED = 201;
    /** {@code 202 Accepted} (HTTP/1.0 - RFC 1945) */
    public static final int SC_ACCEPTED = 202;
    /** {@code 203 Non Authoritative Information} (HTTP/1.1 - RFC 2616) */
    public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
    /** {@code 204 No Content} (HTTP/1.0 - RFC 1945) */
    public static final int SC_NO_CONTENT = 204;
    /** {@code 205 Reset Content} (HTTP/1.1 - RFC 2616) */
    public static final int SC_RESET_CONTENT = 205;
    /** {@code 206 Partial Content} (HTTP/1.1 - RFC 2616) */
    public static final int SC_PARTIAL_CONTENT = 206;
    /**
     * {@code 207 Multi-Status} (WebDAV - RFC 2518)
     * or
     * {@code 207 Partial Update OK} (HTTP/1.1 - draft-ietf-http-v11-spec-rev-01?)
     */
    public static final int SC_MULTI_STATUS = 207;

    // --- 3xx Redirection ---

    /** {@code 300 Mutliple Choices} (HTTP/1.1 - RFC 2616) */
    public static final int SC_MULTIPLE_CHOICES = 300;
    /** {@code 301 Moved Permanently} (HTTP/1.0 - RFC 1945) */
    public static final int SC_MOVED_PERMANENTLY = 301;
    /** {@code 302 Moved Temporarily} (Sometimes {@code Found}) (HTTP/1.0 - RFC 1945) */
    public static final int SC_MOVED_TEMPORARILY = 302;
    /** {@code 303 See Other} (HTTP/1.1 - RFC 2616) */
    public static final int SC_SEE_OTHER = 303;
    /** {@code 304 Not Modified} (HTTP/1.0 - RFC 1945) */
    public static final int SC_NOT_MODIFIED = 304;
    /** {@code 305 Use Proxy} (HTTP/1.1 - RFC 2616) */
    public static final int SC_USE_PROXY = 305;
    /** {@code 307 Temporary Redirect} (HTTP/1.1 - RFC 2616) */
    public static final int SC_TEMPORARY_REDIRECT = 307;

    // --- 4xx Client Error ---

    /** {@code 400 Bad Request} (HTTP/1.1 - RFC 2616) */
    public static final int SC_BAD_REQUEST = 400;
    /** {@code 401 Unauthorized} (HTTP/1.0 - RFC 1945) */
    public static final int SC_UNAUTHORIZED = 401;
    /** {@code 402 Payment Required} (HTTP/1.1 - RFC 2616) */
    public static final int SC_PAYMENT_REQUIRED = 402;
    /** {@code 403 Forbidden} (HTTP/1.0 - RFC 1945) */
    public static final int SC_FORBIDDEN = 403;
    /** {@code 404 Not Found} (HTTP/1.0 - RFC 1945) */
    public static final int SC_NOT_FOUND = 404;
    /** {@code 405 Method Not Allowed} (HTTP/1.1 - RFC 2616) */
    public static final int SC_METHOD_NOT_ALLOWED = 405;
    /** {@code 406 Not Acceptable} (HTTP/1.1 - RFC 2616) */
    public static final int SC_NOT_ACCEPTABLE = 406;
    /** {@code 407 Proxy Authentication Required} (HTTP/1.1 - RFC 2616)*/
    public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
    /** {@code 408 Request Timeout} (HTTP/1.1 - RFC 2616) */
    public static final int SC_REQUEST_TIMEOUT = 408;
    /** {@code 409 Conflict} (HTTP/1.1 - RFC 2616) */
    public static final int SC_CONFLICT = 409;
    /** {@code 410 Gone} (HTTP/1.1 - RFC 2616) */
    public static final int SC_GONE = 410;
    /** {@code 411 Length Required} (HTTP/1.1 - RFC 2616) */
    public static final int SC_LENGTH_REQUIRED = 411;
    /** {@code 412 Precondition Failed} (HTTP/1.1 - RFC 2616) */
    public static final int SC_PRECONDITION_FAILED = 412;
    /** {@code 413 Request Entity Too Large} (HTTP/1.1 - RFC 2616) */
    public static final int SC_REQUEST_TOO_LONG = 413;
    /** {@code 414 Request-URI Too Long} (HTTP/1.1 - RFC 2616) */
    public static final int SC_REQUEST_URI_TOO_LONG = 414;
    /** {@code 415 Unsupported Media Type} (HTTP/1.1 - RFC 2616) */
    public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
    /** {@code 416 Requested Range Not Satisfiable} (HTTP/1.1 - RFC 2616) */
    public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    /** {@code 417 Expectation Failed} (HTTP/1.1 - RFC 2616) */
    public static final int SC_EXPECTATION_FAILED = 417;

    /**
     * Static constant for a 418 error.
     * {@code 418 Unprocessable Entity} (WebDAV drafts?)
     * or {@code 418 Reauthentication Required} (HTTP/1.1 drafts?)
     */
    // not used
    // public static final int SC_UNPROCESSABLE_ENTITY = 418;

    /**
     * Static constant for a 419 error.
     * {@code 419 Insufficient Space on Resource}
     * (WebDAV - draft-ietf-webdav-protocol-05?)
     * or {@code 419 Proxy Reauthentication Required}
     * (HTTP/1.1 drafts?)
     */
    public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419;
    /**
     * Static constant for a 420 error.
     * {@code 420 Method Failure}
     * (WebDAV - draft-ietf-webdav-protocol-05?)
     */
    public static final int SC_METHOD_FAILURE = 420;
    /** {@code 422 Unprocessable Entity} (WebDAV - RFC 2518) */
    public static final int SC_UNPROCESSABLE_ENTITY = 422;
    /** {@code 423 Locked} (WebDAV - RFC 2518) */
    public static final int SC_LOCKED = 423;
    /** {@code 424 Failed Dependency} (WebDAV - RFC 2518) */
    public static final int SC_FAILED_DEPENDENCY = 424;

    // --- 5xx Server Error ---

    /** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
    public static final int SC_INTERNAL_SERVER_ERROR = 500;
    /** {@code 501 Not Implemented} (HTTP/1.0 - RFC 1945) */
    public static final int SC_NOT_IMPLEMENTED = 501;
    /** {@code 502 Bad Gateway} (HTTP/1.0 - RFC 1945) */
    public static final int SC_BAD_GATEWAY = 502;
    /** {@code 503 Service Unavailable} (HTTP/1.0 - RFC 1945) */
    public static final int SC_SERVICE_UNAVAILABLE = 503;
    /** {@code 504 Gateway Timeout} (HTTP/1.1 - RFC 2616) */
    public static final int SC_GATEWAY_TIMEOUT = 504;
    /** {@code 505 HTTP Version Not Supported} (HTTP/1.1 - RFC 2616) */
    public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;

    /** {@code 507 Insufficient Storage} (WebDAV - RFC 2518) */
    public static final int SC_INSUFFICIENT_STORAGE = 507;

}

7.分页模块封装

7.1.分页请求封装

package cn.hcnet2006.blog.hcnetwebsite.page;
import java.util.HashMap;
import java.util.Map;

/**
 * 分页请求
 * @author Louis
 * @date Jan 12, 2019
 */
public class PageRequest {
    /**
     * 当前页码
     */
    private int pageNum = 1;
    /**
     * 每页数量
     */
    private int pageSize = 10;

    public PageRequest(int pageNum, int pageSize, Map<String, Object> params) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.params = params;
    }

    /**
     * 查询参数
     */

    private Map<String, Object> params = new HashMap<>();

    public int getPageNum() {
        return pageNum;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public Map<String, Object> getParams() {
        return params;
    }
    public void setParams(Map<String, Object> params) {
        this.params = params;
    }
    public Object getParam(String key) {
        return getParams().get(key);
    }

}

7.2分页结果封装

package cn.hcnet2006.blog.hcnetwebsite.page;


import java.util.List;

/**
 * 分页返回结果
 * @author Louis
 * @date Jan 12, 2019
 */
public class PageResult {
    /**
     * 当前页码
     */
    private int pageNum;
    /**
     * 每页数量
     */
    private int pageSize;
    /**
     * 记录总数
     */
    private long totalSize;
    /**
     * 页码总数
     */
    private int totalPages;
    /**
     * 分页数据
     */
    private List<?> content;
    public int getPageNum() {
        return pageNum;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public long getTotalSize() {
        return totalSize;
    }
    public void setTotalSize(long totalSize) {
        this.totalSize = totalSize;
    }
    public int getTotalPages() {
        return totalPages;
    }
    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
    public List<?> getContent() {
        return content;
    }
    public void setContent(List<?> content) {
        this.content = content;
    }
}

7.3.MyBatis分页助手

package cn.hcnet2006.blog.hcnetwebsite.page;

import cn.hcnet2006.blog.hcnetwebsite.utils.ReflectionUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import java.util.List;

/**
 * MyBatis 分页查询助手
 * @author Louis
 * @date Jan 12, 2019
 */
public class MybatisPageHelper {

    public static final String findPage = "findPage";

    /**
     * 分页查询, 约定查询方法名为 “findPage”
     * @param pageRequest 分页请求
     * @param mapper Dao对象,MyBatis的 Mapper
     * @param
     * @return
     */
    public static PageResult findPage(PageRequest pageRequest, Object mapper) {
        return findPage(pageRequest, mapper, findPage);
    }

    /**
     * 调用分页插件进行分页查询
     * @param pageRequest 分页请求
     * @param mapper Dao对象,MyBatis的 Mapper
     * @param queryMethodName 要分页的查询方法名
     * @param args 方法参数
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static PageResult findPage(PageRequest pageRequest, Object mapper, String queryMethodName, Object... args) {
        // 设置分页参数
        int pageNum = pageRequest.getPageNum();
        int pageSize = pageRequest.getPageSize();
        PageHelper.startPage(pageNum, pageSize);
        // 利用反射调用查询方法
        Object result = ReflectionUtils.invoke(mapper, queryMethodName, args);
        if(result == null){
            System.out.println("result is null");
        }
        return getPageResult(pageRequest, new PageInfo((List) result));
    }

    /**
     * 将分页信息封装到统一的接口
     * @param pageRequest
     * @param
     * @return
     */
    private static PageResult getPageResult(PageRequest pageRequest, PageInfo<?> pageInfo) {
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(pageInfo.getPageNum());
        pageResult.setPageSize(pageInfo.getPageSize());
        pageResult.setTotalSize(pageInfo.getTotal());
        pageResult.setTotalPages(pageInfo.getPages());
        pageResult.setContent(pageInfo.getList());
        return pageResult;
    }

}

7.4.反射相关辅助方法

package cn.hcnet2006.blog.hcnetwebsite.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射相关辅助方法
 * @author Louis
 * @date Aug 19, 2018
 */
public class ReflectionUtils {


    /**
     * 根据方法名调用指定对象的方法
     * @param object 要调用方法的对象
     * @param method 要调用的方法名
     * @param args 参数对象数组
     * @return
     */
    public static Object invoke(Object object, String method, Object... args) {
        Object result = null;
        Class<? extends Object> clazz = object.getClass();
        System.out.println("class:"+clazz.getName());
        System.out.println("method:"+method);
        System.out.println("args:"+args.toString());
        Method queryMethod = getMethod(clazz, method, args);
        if(queryMethod != null) {
            try {
                result = queryMethod.invoke(object, args);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("method is null");
            try {
                throw new NoSuchMethodException(clazz.getName() + " 类中没有找到 " + method + " 方法。");
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 根据方法名和参数对象查找方法
     * @param clazz
     * @param name
     * @param args 参数实例数据
     * @return
     */
    public static Method getMethod(Class<? extends Object> clazz, String name, Object[] args) {
        Method queryMethod = null;
        System.out.println("the method we are find");
        System.out.println("see all method");
        Method[] methods = clazz.getMethods();
        for(Method method:methods) {
            System.out.println("method:"+method.getName());
            if(method.getName().equals(name)) {
                Class<?>[] parameterTypes = method.getParameterTypes();
                System.out.println("the ards length we are find is:"+args.length);
                System.out.println("the ards length will be compared:"+parameterTypes.length);

                if(parameterTypes.length == args.length) {
                    boolean isSameMethod = true;
                    for(int i=0; i<parameterTypes.length; i++) {
                        Object arg = args[i];
                        if(arg == null) {
                            arg = "";
                        }
                        System.out.println("type of the method we are find:"+args[i].getClass().toString());
                        System.out.println("type of the method will be compared:"+parameterTypes[i].toString());
                        if(!parameterTypes[i].equals(args[i].getClass())) {
                            isSameMethod = false;
                            System.out.println("类型不一样");
                        }
                    }
                    if(isSameMethod) {
                        queryMethod = method;
                        break ;
                    }
                }
            }
        }
        return queryMethod;
    }
}

8.通用CURD接口

package cn.hcnet2006.blog.hcnetwebsite.service;



import cn.hcnet2006.blog.hcnetwebsite.page.PageRequest;
import cn.hcnet2006.blog.hcnetwebsite.page.PageResult;

import java.util.List;

/**
 * 通用CURD 接口
 * @param <T>
 */
public interface CurdService<T> {
    /**
     * 保存操作
     * @param record
     * @return
     */
    int save(T record);

    /**
     * 删除操作
     * @param record
     * @return
     */
    int delete(T record);

    /**
     * 批量删除操作
     * @param records
     * @return
     */
    int delete(List<T> records);

    /**
     * 根据ID查询
     * @param id
     * @return
     */
    T findById(Long id);

    /**
     * 分页查询
     * @param pageRequest
     * @return
     */
    PageResult findPage(PageRequest pageRequest);

}

9.swagger聚合文档设置

package cn.hcnet2006.blog.hcnetwebsite.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {
        //添加head参数start
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
        tokenPar.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
        pars.add(tokenPar.build());
        //添加head参数end


        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
                .globalOperationParameters(pars)
                .apiInfo(apiInfo());
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("后台接口文档与测试")
                .description("这是一个给app端人员调用server端接口的测试文档与平台")
                .version("1.0.0")
                .termsOfServiceUrl("http://terms-of-services.url")
                //.license("LICENSE")
                //.licenseUrl("http://url-to-license.com")
                .build();
    }

}

10.集成阿里云OSS

仅仅使用上传功能,上传后返回下载链接

package cn.hcnet2006.blog.hcnetwebsite.utils;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * OSS文件上传
 */
public class OSSUtils {
    @Autowired
    //private  static OSSConstant ossConstant;
    static String bucketName = "hcnetxxxx-apk";

    static String accessKeyId = "LTAI4Fn8xxxxxxxxucSR5AX";

    static String accessKeySecret = "yuYPFquHRK3xxxxxxxMBUaWjLdC";

    static String endpoint = "oss-cn-shenzhen.aliyuncs.com";
    private static OSS ossClient ;
    private  static  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    public static String upload(File file,String apkName){
        ossClient =  new OSSClientBuilder().build(endpoint,accessKeyId,
                accessKeySecret);

        System.out.println("accessKeyId2:"+accessKeyId);

        if(file == null){
            return null;
        }
        String dateStr = sdf.format(new Date());


        try{
            //容器不存在就创建
            if(!ossClient.doesBucketExist(bucketName)){
                ossClient.createBucket(bucketName);
                CreateBucketRequest cbr = new
                        CreateBucketRequest(bucketName);
                cbr.setCannedACL(
                        CannedAccessControlList.Private
                );
                ossClient.createBucket(cbr);
            }
            //上传文件

            InputStream is = new FileInputStream(file);
            PutObjectResult result = ossClient.putObject(bucketName,apkName,file);
            //System.out.println(result.getRequestId());
           // String uri = result.getResponse().getUri();
            // 设置这个文件地址的有效时间
            Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);

            String url = ossClient.generatePresignedUrl(bucketName, apkName, expiration).toString();

            System.out.println("object:"+apkName+"存入成功");
            System.out.println("上传路径:"+url);
            return url;
        }catch (OSSException oe){
            oe.printStackTrace();
        }catch (ClientException | FileNotFoundException ce){
            ce.printStackTrace();
        }finally{
            ossClient.shutdown();
        }
        return null;
    }
    public static void download(String apkName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
                    //设置文件内容
            resp.setContentType("application/vnd.android.package-archive");
            //下载显示的文件名
            String apk_name = apkName;
            //下载显示文件名解决中文乱码问题
            //在下载之前首先判断是否是微软浏览器,如果是,用UTF-8编码,
            //如果不是,用万能解码
            //这样就可以在IE8-11,EDGE,FIXBO一级Chrome浏览器下载文件时,不会中文乱码了
            boolean isMSIE = HttpUtils.isMSBrowser(req);
            //如果是IE浏览器
            if(isMSIE){
                apk_name = URLEncoder.encode(apk_name,"UTF-8");
            }else{
                //其他浏览器
                apk_name = new String(apk_name.getBytes("UTF-8"),"ISO-8859-1");
            }
            //设置response的Content-disposition时,apk_name的值要加上双引号如果不佳双引号
            //在火狐下载数据时,如果文件名是英文加中文的组合,那么火狐在下载时,文件名只有英文部分
            //只有加了双引号之后,文件名和代码设置的文件名一致,因为这个双引号是在字符串中的,所以需
            //要加反斜杠来转义

            resp.setHeader("Content-disposition","attachment;filename:"+apk_name);
            //设置文件大小,这样就可以在下载时,显示文件的大小
            //resp.setContentLength(Integer.parseInt("7629672"));
            //读取要下载的文件保存到文件输入流
            OSS ossClient =  new OSSClientBuilder().build("oss-cn-shenzhen.aliyuncs.com","LTAI4Fn8YhRW2FkbpucSR5AX","yuYPFquHRK3UHHKq3YlV0MBUaWjLdC");
            OSSObject ossObject = ossClient.getObject("hcnet2006-file-apk",apkName);

            System.out.println("Object content:");
            InputStream is = ossObject.getObjectContent();
        BufferedInputStream in = new BufferedInputStream(is);
            //InputStream in = new FileInputStream(apk_url);
            //创建文件输出流
            OutputStream out = resp.getOutputStream();
            //创建缓冲区
            byte buffer[] = new byte[1024];
            int len = 0;
            while((len = in.read(buffer)) > 0){
                out.write(buffer,0,len);
            }
            //关闭输入流
            in.close();
            //关闭输出流
            out.close();
            //关闭OSSClient;
            ossClient.shutdown();
    }

}

11.APK上传(另外一个项目)参考

package cn.hcnet2006.blog.uploadapk.controller;

import brave.http.HttpRequest;
import cn.hcnet2006.blog.uploadapk.bean.SysApk;
import cn.hcnet2006.blog.uploadapk.config.OSSConfig;
import cn.hcnet2006.blog.uploadapk.constant.OSSConstant;
import cn.hcnet2006.blog.uploadapk.http.HttpResult;
import cn.hcnet2006.blog.uploadapk.page.PageRequest;
import cn.hcnet2006.blog.uploadapk.page.PageResult;
import cn.hcnet2006.blog.uploadapk.service.SysApkService;
import cn.hcnet2006.blog.uploadapk.utils.ApkInfoUtil;
import cn.hcnet2006.blog.uploadapk.utils.HttpUtils;
import cn.hcnet2006.blog.uploadapk.utils.OSSUtils;
import com.aliyun.oss.OSS;
//import com.google.gson.internal.$Gson$Preconditions;
//import com.netflix.ribbon.proxy.annotation.Http;
import io.swagger.annotations.*;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Api(tags = "上传信息接口")
@RestController
@RequestMapping("/upload")
public class UploadController {
    @Autowired
    private SysApkService sysApkService;

    //文件按时间结构存储
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    @ApiOperation(value = "文件上传",notes = "文件上传")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query",name = "createBy",dataType = "String",required = true)
    })
    //@PreAuthorize("hasAuthority('ROLE_USER')")
    @PostMapping("/apk")
    public HttpResult upload(@ApiParam(value = "uploadFile",required = true) MultipartFile uploadFile,String createBy, HttpServletRequest req) throws NullPointerException, IOException {


        //获取文件大小
        String apkSize = uploadFile.getSize()+"";
        //应用类型
        String cType = uploadFile.getContentType();
        System.out.println("应用类型:"+cType);
        //规划文件上传路径
        String realPath = "/home/lidengyin/Documents/uploadFile/apk/";
        //文件目录格式,时期划分
        String format = sdf.format(new Date());
        //指定上传文件目录
        File folder = new File(realPath + format);
        if(!folder.isDirectory()){
            //生成路径下所有目录
            folder.mkdirs();
        }

        //文件上传名

        String apkOldName = uploadFile.getOriginalFilename();
        System.out.println("fileName:"+apkOldName);
        //文件存储名:UUID+文件类型后缀
        String apkStoName = UUID.randomUUID().toString()+
                apkOldName.substring(apkOldName.lastIndexOf("."),apkOldName.length());
        //
        try{
            //将上传文件以指定名称上传到指定文件夹
            uploadFile.transferTo(new File(folder, apkStoName));
            //获取文件在服务器存储路径
            String filePath = folder.getPath()+"/"+apkStoName;

            System.out.println("filePath:"+filePath);

            File convFile = new File(filePath);

            Map<String,Object> apkInfo = ApkInfoUtil.readAPK(convFile);
            //应用名
            String apkName = (String) apkInfo.get("name");
            //应用包
            String pkName = (String) apkInfo.get("pkName");
            //版本名
            String vName = (String) apkInfo.get("vName");
            //版本号
            long vCode = (long) apkInfo.get("vCode");
            System.out.println("名称:"+apkName);
            System.out.println("包名:"+pkName);
            System.out.println("版本名:"+vName);
            System.out.println("版本号:"+vCode);
            //设置SysApk
            SysApk sysApk = new SysApk();
            sysApk.setApkName(apkName);
            sysApk.setApkPk(pkName);
            sysApk.setApkVc(vCode);
            sysApk.setApkVn(vName);
            sysApk.setCreateBy(createBy);
            sysApk.setCreateTime(new Date());
            sysApk.setLastUpdateBy(createBy);
            sysApk.setLastUpdateTime(new Date());
            sysApk.setApkSize(apkSize);
            //sysApk.setApkUrl(filePath);
            sysApk.setDelFlag((byte)0);

            String apkUrl = OSSUtils.upload(convFile,apkName);
            apkUrl = apkUrl.substring(0,apkUrl.indexOf("?"));
            System.out.println("apkurl:"+apkUrl);
            System.out.println("url:"+sysApk.getApkUrl());
            sysApk.setApkUrl(apkUrl);
            sysApkService.save(sysApk);
            return HttpResult.ok(filePath);
        }catch (IOException e){
            e.printStackTrace();

        }
        return HttpResult.error("上传失败");
    }

//    @ApiOperation(value = "下载信息接口",notes = "下载信息接口")
//    @ApiImplicitParams({
//            @ApiImplicitParam(type = "query",name = "id",value = "资源序号",required = true)
//    })
//    @PostMapping("/download")
//    //@PreAuthorize("hasAuthority('ROLE_USER')")
//    @CrossOrigin(origins = "*", maxAge = 3600, allowedHeaders = "*",allowCredentials = "true")
//    public  String  download(Long id, HttpServletResponse resp,HttpServletRequest req){
//        try{
//            SysApk sysApk = sysApkService.findById(id);
//            if (sysApk.getDelFlag() == -1){
//                return "链接失效";
//            }
//            OSSUtils.download("海行健V2.0",req,resp);
//            System.out.println("id:"+id);
//            //根据主键获取对应文件
//            SysApk sysApk = sysApkService.findById(Long.parseLong(id));
//            System.out.println("name:"+sysApk.getApkName());
//            System.out.println("url:"+sysApk.getApkUrl());
//
//            //文件大小
//            String content_length = sysApk.getApkSize();
//            //文件下载路径
//            String apk_url = sysApk.getApkUrl();
//            //生成文件
//            File file = new File(apk_url);
//            System.out.println("fileName:"+file.getName());
//            System.out.println("fileIsDirectory:"+file.isDirectory());
//
//            //设置文件内容
//            resp.setContentType("application/octet-stream");
//            //下载显示的文件名
//            String apk_name = sysApk.getApkName();
//            //下载显示文件名解决中文乱码问题
//            //在下载之前首先判断是否是微软浏览器,如果是,用UTF-8编码,
//            //如果不是,用万能解码
//            //这样就可以在IE8-11,EDGE,FIXBO一级Chrome浏览器下载文件时,不会中文乱码了
//            boolean isMSIE = HttpUtils.isMSBrowser(req);
//            //如果是IE浏览器
//            if(isMSIE){
//                apk_name = URLEncoder.encode(apk_name,"UTF-8");
//            }else{
//                //其他浏览器
//                apk_name = new String(apk_name.getBytes("UTF-8"),"ISO-8859-1");
//            }
//            //设置response的Content-disposition时,apk_name的值要加上双引号如果不佳双引号
//            //在火狐下载数据时,如果文件名是英文加中文的组合,那么火狐在下载时,文件名只有英文部分
//            //只有加了双引号之后,文件名和代码设置的文件名一致,因为这个双引号是在字符串中的,所以需
//            //要加反斜杠来转义
//
//            resp.setHeader("Content-disposition","attachment;filename:"+apk_name);
//            //设置文件大小,这样就可以在下载时,显示文件的大小
//            resp.setContentLength(Integer.parseInt(content_length));
//
//            //读取要下载的文件保存到文件输入流
//            InputStream in = new FileInputStream(apk_url);
//            //创建文件输出流
//            OutputStream out = resp.getOutputStream();
//            //创建缓冲区
//            byte buffer[] = new byte[1024];
//            int len = 0;
//            while((len = in.read(buffer)) > 0){
//                out.write(buffer,0,len);
//            }
//            //关闭输入流
//            in.close();
//            //关闭输出流
//            out.close();
//            return HttpResult.ok("下载成功");
//        }catch (Exception e){
//            e.printStackTrace();
//            //return HttpResult.error("下载失败");
//        }
//    }
    @ApiOperation(value = "根据删除标志,分页查看上传文件",notes = "根据删除标志,分页查看上传文件")
    @ApiImplicitParams({
//            @ApiImplicitParam(type = "query", name = "pageNum", value = "页码",required = true),
//            @ApiImplicitParam(type = "query", name = "pageSize", value = "行数",required = true),
//            @ApiImplicitParam(type = "query",name = "delFlag", value = "删除标志,-1为删除,0为正常",required = true)
    })
    @PostMapping("/select/delFlag")
    @PreAuthorize("hasAuthority('ROLE_USER')")
    @CrossOrigin(maxAge = 3600, origins = "*", allowedHeaders = "*",allowCredentials = "true")
    public HttpResult selectByDelFlag(@RequestBody PageRequest pageRequest){
        Byte delFlag = Byte.parseByte( pageRequest.getParam("delFlag")+"") ;
        Map<String ,Object> map = new HashMap<>();
        map.put("delFlag", delFlag);
        pageRequest.setParams(map);
        System.out.println(pageRequest.getParam("delFlag"));
        PageResult pageResult = sysApkService.findPage(pageRequest);
        return HttpResult.ok(pageResult);
    }

    @ApiOperation(value = "修改可用性",notes = "修改可用性")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query",name = "id",value = "ID",required = true),
            @ApiImplicitParam(type = "query",name = "delFlag",value = "删除标志,-1删除,0正常",required = true)
    })
    @PostMapping("/update/id")
    @PreAuthorize("hasAuthority('ROLE_USER')")
    public HttpResult updateDelFlagById(String id, String delFlag){
        try{
            SysApk sysApk = new SysApk();
            sysApk.setId(Long.parseLong(id));
            sysApk.setDelFlag(Byte.parseByte(delFlag));
            int result = sysApkService.delete(sysApk);
            return HttpResult.ok(sysApk);
        }catch (Exception e){
            return HttpResult.error("修改失败");
        }
    }
}

12.简单用户注册实现,通过捕获异常

package cn.hcnet2006.blog.hcnetwebsite.controller;

import cn.hcnet2006.blog.hcnetwebsite.bean.SysUser;
import cn.hcnet2006.blog.hcnetwebsite.http.HttpResult;
import cn.hcnet2006.blog.hcnetwebsite.service.SysUserService;
import cn.hcnet2006.blog.hcnetwebsite.util.OSSUtils;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;

@Api(tags = "用户信息接口")
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private SysUserService sysUserService;
    //private String url = "/usr/local/spring";
    @ApiOperation(value = "用户注册",notes = "用户注册" +
            "参数包括:" +
            "1.")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "query", name = "name",value = "用户名",required = true),
            @ApiImplicitParam(type = "query", name = "password",value = "密码",required = true),
            @ApiImplicitParam(type = "query", name = "deptId",value = "所属方向ID",required = true),
            @ApiImplicitParam(type = "query", name = "grade",value = "年级,比如2018",required = true),
            @ApiImplicitParam(type = "query", name = "email",value = "邮箱,确保格式正确",required = true),
            @ApiImplicitParam(type = "query", name = "mobile",value = "手机,确保格式正确",required = true),
            @ApiImplicitParam(type = "query", name = "createBy",value = "创建者",required = true),
            //@ApiImplicitParam(type = "query", name = "createTime",value = "创建时间",required = true)
    })
    @PostMapping("/save")
    public HttpResult register(SysUser sysUser, @ApiParam(value = "uploadFile", required = true) MultipartFile uploadFile,
                               HttpServletRequest request) throws FileNotFoundException {

        //新建暂时缓存目录,该目录一定存在
        String url = ResourceUtils.getURL("").getPath()+uploadFile.getOriginalFilename();
        System.out.println(url);
        File folder = new File(url);
        try{
            //转义文件到服务器
            uploadFile.transferTo(folder);
            //从服务器获取文件传递到阿里云OSS.返回下载链接地址
            String avator_url = OSSUtils.upload(folder,sysUser.getName()+".jpg");
            //删除服务器缓存文件
            folder.delete();
            //设置属性
            //设置用户头像
            sysUser.setAvator(avator_url);
            //设置创建时间
            sysUser.setCreateTime(new Date());
            //设置更新时间
            sysUser.setLastUpdateTime(new Date());
            //设置创建者
            sysUser.setLastUpdateBy(sysUser.getCreateBy());
            //删除标志
            sysUser.setDelFlag((byte)0);
            //保存
            sysUserService.save(sysUser);
            return HttpResult.ok(sysUser);
        }catch (DuplicateKeyException e){
            return HttpResult.error("重复注册");
        }catch (IOException e){
            e.printStackTrace();
            return HttpResult.error("注册失败");
        }

    }
}

13.工具类(旧),可用的仅有捕捉图片第一帧

package cn.hcnet2006.blog.hcnetwebsite.util;

import cn.hcnet2006.blog.hcnetwebsite.http.HttpResult;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;

public class ImageAndVideoUtils {

    public static  void findImgName(String imgUrl, MultipartFile multipartFile)throws IOException {

        //获得文件所在目录
        File folder = new File(imgUrl);
        //添加目录
        if(!folder.isDirectory()){
            folder.mkdirs();
        }
        try{
            //转移加载文件
            multipartFile.transferTo(folder);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static HttpResult showImage(String imageUrl,HttpServletResponse response
                                        )throws IOException{
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        File file = new File(imageUrl);
        BufferedImage bi = ImageIO.read(new FileInputStream(file));
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi,"jpg",out);
        try{
            out.flush();
        }finally {
            out.close();
        }
        return null;
    }
    /**
     * 捕捉图片第一帧
     * @throws Exception
     */
    public static void fetchFrame(String videoUrl,String imgUrl)throws Exception{
//

        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videoUrl);
        Java2DFrameConverter converter = new Java2DFrameConverter();
        frameGrabber.start();
        //解码长度
        int length = frameGrabber.getLengthInFrames();
        //时间
        int i = 0;
        Frame frame = null;
        while(i < length){
            //过滤前五帧,避免出现全黑的图片
            frame = frameGrabber.grabFrame();
            if(i > 10 && (frame.image != null)){
                break;
            }
            i ++;
        }
        // Frame frame = frameGrabber.grabFrame();
        BufferedImage bufferedImage = converter.convert(frame);
        //照片保存文件夹
        File targetFile = new File(imgUrl);
        //文件夹不存在就新建
        if(!targetFile.isDirectory()){
            targetFile.mkdirs();
        }
        //写入文件夹,以jpg图片格式
        ImageIO.write(bufferedImage, "jpg", targetFile);
        //停止转化为帧
        frameGrabber.stop();
    }

    public static HttpResult showVideo( String videoUrl,HttpServletResponse response)throws IOException{
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("video/mp4");
        FileInputStream fis = null;
        OutputStream os = null ;
        File file = new File(videoUrl);
        fis = new FileInputStream(file);
        int size = fis.available(); // 得到文件大小
        byte data[] = new byte[size];
        fis.read(data); // 读数据
        fis.close();
        fis = null;
        response.setContentType("video/mp4"); // 设置返回的文件类型
        os = response.getOutputStream();
        os.write(data);
        try{
            os.flush();
        }finally {
            os.close();
        }
        return null;
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值