Springboot知识点小结

Springboot项目热部署

一、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional><!-- 防止将devtools依赖传递到其他模块中 -->
</dependency>

二、IDEA中的设置

1、File | Settings | Build, Execution, Deployment | Compiler -----> build project automatically 对勾;

2、ctrl+shift+alt+/ Registry;

3、选择compiler.automake.allow.when.app.running在后面的方框中打上√;

4、在IDEA工具类上方的Application再点击Edit Configurations...

springboot中Running Application Update Policies,下方两个选项,选择Update classes and resources。

springboot项目中加载properties文件

//confpath为properties文件的地址  如: "/license/licenseMakeConf.properties"
public LicenseMake(String confPath) {
    // 获取参数
    Properties prop = new Properties();
    try (InputStream in = getClass().getResourceAsStream(confPath)) {
        prop.load(in);
    } catch (IOException e) {
        log.error("CreateLicense Properties load inputStream error.", e);
    }
    //common param 使用参数
    priAlias = prop.getProperty("private.key.alias");
    privateKeyPwd = prop.getProperty("private.key.pwd");
    keyStorePwd = prop.getProperty("key.store.pwd");
    subject = prop.getProperty("subject");
    priPath = prop.getProperty("priPath");
}

@RequestBody、@RequestParam

@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);使用@RequestBody接收数据时,一般都用POST方式进行提交。

在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

使用@requestBody注解时:

一般传递对象,以JSON的形式进行传递,请求用POST方式提交;
如果对象某个参数没有值,直接不写这个属性即可。

@RequestParam的使用方法:

public String requestparam(  
@RequestParam(value="username", required=true, defaultValue="zhang") String username)

如果传递多个值,我们可以适当改变username的类型。

三、springboot项目打war包,部署到tomcat

1.配置项目

a.修改启动类

继承SpringBootServletInitializer类,并重写覆盖configure方法,代码如下:

public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }
}

b.剔除依赖

pom文件中添加一下依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-start-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

设置项目打包方式

为打war包,注意添加第四行到对应位置就好

<groupId>com.zony</groupId>
<artifactId>PEP_PDFSecurity</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>PEP_PDFSecurity</name>
2.通过Maven的clean package进行打包
3.在第2步过程中,可能会出现错误

解决方案: 在pom.xml文件中引入以下依赖

<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>javax.servlet-api</artifactId>
     <version>3.1.0</version>
     <scope>provided</scope>
</dependency>
4.部署

把target目录下的war包放到tomcat的webapps目录下,
去bin文件夹startup.bat启动tomcat,即可自动解压war包,并部署。

5.测试

localhost:8080/Ingship/user/info?token=admin-token

Ingship是war包解析后的文件夹的名称,相当与IDEA项目中配置的content-path

四、日志

1.配置文件中添加配置
logging:
  level:
    root: INFO          #日志文件名称
  config: classpath:logback-spring.xml
2.新建日志文件配置信息

和yml配置文件在统一目录下

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<!--    <property name="LOG_HOME" value="C:/log" />D:\log-->
    <property name="LOG_HOME" value="./my-logs" />
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!--设置控制台的输出级别为“ERROR”级别-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!--设置控制台的日志输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH} [%thread] %-5level %logger{50} - %msg  %n</pattern>
        </encoder>
    </appender>

    <!--info级别的日志文件设置-->
    <appender name="INFO_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志级别设置-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!--临时文件的保存位置及名称-->
        <File>${LOG_HOME}/my-info.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--临时文件大小保存到一定要求后,更改文件名,成为历史日志文件-->
            <fileNamePattern>${LOG_HOME}/info-%d{yyyyMMdd}.log.%i</fileNamePattern>
            <!--保存文件的要求,达到要求后,创建新的日志文件-->
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>20MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <!--控制日志信息保存格式-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH} %-5level %logger -%msg%n</pattern>
        </layout>
    </appender>

    <!--error级别的日志文件设置-->
    <appender name="ERROR_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <File>${LOG_HOME}/my-error.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/error-%d{yyyyMMdd}.log.%i
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>20MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <!--控制日志信息保存格式-->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH} %-5level %logger -%msg%n</pattern>
        </layout>
    </appender>

    <!-- 日志输出级别 -->
    <root level="ERROR">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="ERROR_FILE"/>
        <appender-ref ref="INFO_FILE"/>
    </root>
</configuration>

五、IE浏览器下ajax请求不走后台

1.问题出现原因
1、在ie浏览器下,chrome浏览器没有此问题
2、请求的url和参数和上一次的请求一样
3、请求方式为get而不是post
2.解决办法
与出现原因对应的解决方法
1、不使用ie浏览器(不太符合实际情况)
2、在正常已有的请求参数后加一个随机数或时间戳
3、将请求类型设为post  (通常选择这种方式解决此问题)
4、将ajax的cache属性设为false(默认为true),这样就不会使用浏览器的缓存

六、项目中读取配置文件的绝对路径

//获取项目的文件夹绝对路径  GlobalsUtil当前类名称
//path不以"/"开头:当前类所在的包目录
//path以"/"开头:class path,即当前项目
sysRootDir = GlobalsUtil.class.getResource("/").getPath();
try {
    //解决路径中文乱码
    sysRootDir = URLDecoder.decode(sysRootDir, "UTF-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}
System.out.println("-------------------路径:"+sysRootDir);

七、文件流读取文件并作为参数传递

当文件下载后保存在本地服务器,其他服务器想要获取本地的文件时,可以使用此方法将文件作为流传递出去。

public void downloadFile(HttpServletRequest request, HttpServletResponse response, String filePath) {
    //++++++此处为返回对象+++++++
    ServletOutputStream ouStream = null;
    InputStream inStream = null;
    String responseFileName;// 显示文件名
    String responseContentType;// 显示文件类型
    int responseContentLength;// 显示字节数
    try {
        //++++++此处为返回对象+++++++
        ouStream = response.getOutputStream();
        File tmpFile = new File(filePath);
        responseFileName = tmpFile.getName();
        responseContentType = ConvertType.getType(tmpFile.getName());
        responseContentLength = (int) tmpFile.length();
        inStream = new FileInputStream(tmpFile);
        response.setContentType(responseContentType);
        response.setHeader("Content-disposition", "attach;filename=" + UriUtils.encode(responseFileName, "UTF-8"));
        response.setHeader("Pragma", "no-cache");
        response.setContentLength(responseContentLength);
        byte[] buffer = new byte[5242880];
        int len;
        while ((len = inStream.read(buffer)) > 0) {
            //++++++将文件写入+++++++
            ouStream.write(buffer, 0, len);
        }
    } catch (Exception e) {
        log.error(e.getMessage(), e);
    } finally {
        if (inStream != null) {
            try {
                inStream.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        if (ouStream != null) {
            try {
                ouStream.flush();
                ouStream.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
    }

八、MultipartFile和FIle类型相互转换

MultipartFile转换为FIle

file为MultipartFile,转换完成后在本地c盘下可看到对应的文件
String filePath = "c:\\";
File receiveFile = new File(filePath);
//MultipartFile转换为File
file.transferTo(receiveFile);

File转换为MultipartFIle

引入依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
//根据文件路径获取MultipartFile文件
FileItem fileItem = getMultipartFile(file,"tempItem");
CommonsMultipartFile multipartFile = new CommonsMultipartFile(fileItem);

九、清空某个文件夹

public static boolean deleteDir(String path){
    File file = new File(path);
    if(!file.exists()){//判断是否待删除目录是否存在
        System.err.println("The dir are not exists!");
        return false;
    }

    String[] content = file.list();//取得当前目录下所有文件和文件夹
    for(String name : content){
        File temp = new File(path, name);
        if(temp.isDirectory()){//判断是否是目录
            deleteDir(temp.getAbsolutePath());//递归调用,删除目录里的内容
            temp.delete();//删除空目录
        }else{
            if(!temp.delete()){//直接删除文件
                System.err.println("Failed to delete " + name);
            }
        }
    }
    return true;
}

十、springboot集成数据库mysql和hibernate

1.导入依赖
<!--连接mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!--添加JDBC依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- jpa配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
</dependency>
<!--lombok依赖-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>
2.在springboot的yml配置文件里配置mysql的连接信息
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/pep_pdfsecurity?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    show-sql: true
  servlet:
    multipart:
      #上传每个文件的配置最大为1GB
      max-file-size: 1GB
      #单次请求的文件的总数不能大于4GBMB
      max-request-size: 4GB
3.创建工具类Result
package com.zony.lngship.util;

/**
*@Description 返回结果数据
*@Param
*@Return
*@Author ChuXu
*@Date 2021/11/18
*@Time 9:45
*/
public class Result {
    //相应码
    private Integer code;
    //信息
    private String message;
    //返回数据
    private Object data;

    public Result() {
    }

    public Result(Integer code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

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

    public Object getData() {
        return data;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
4.创建实体类对应数据库表
package com.zony.app.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
/**
*@Description 文件表
*@Param
*@Return
*@Author ChuXu
*@Date 2022/3/24
*@Time 17:08
*/
@Entity     //表名
@Table(name = "file_info")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FileInfo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private String id;

    @Column(name = "file_name")
    private String fileName;

    @Column(name = "file_path")
    private String filePath;

    @Column(name = "file_size")
    private String fileSize;

    @Column(name = "page")
    private String page;

    @Override
    public String toString() {
        return "File{" +
            "id='" + id + '\'' +
            ", fileName='" + fileName + '\'' +
            ", filePath='" + filePath + '\'' +
            ", fileSize='" + fileSize + '\'' +
            ", page='" + page + '\'' +
            '}';
    }
}
5.创建Repository 数据库的访问接口
package com.zony.app.respository;

import com.zony.app.entity.FileInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

												//表名称     主键类型
public interface FileInfoDao extends JpaRepository<FileInfo,String> {

    //根据id查询文件信息
    @Query(value = "select * from file_info where id = ?1",nativeQuery = true)
    FileInfo seleteFileInfoById(String id);

    //根据id删除文件信息
    @Transactional
    @Modifying
    @Query(value = "delete from file_info where id = ?1",nativeQuery = true)
    void deleteFileInfoById(String id);

    //修改文件信息
    @Transactional
    @Modifying
    @Query(value = "update file_info f set f.file_name = ?2,f.file_path = ?3,f.file_size = ?4,f.page = ?5 where f.id = ?1",nativeQuery = true)
    void updateFileInfo(String id,String fileName,String filePath,String fileSize,String page);
}
6.创建服务层service
package com.zony.app.service;

import com.zony.app.entity.FileInfo;

import java.util.List;

public interface FileInfoService {

    public List<FileInfo> selectAllFileInfo();

    public FileInfo seleteFileInfoById(String id);

    public void insertFileInfo(FileInfo fileInfo);

    public void deleteFileInfoById(String id);

    public void updateFileInfo(FileInfo fileInfo);
}
7.创建实现类impl
package com.zony.app.service.serviceimpl;
import com.zony.app.entity.FileInfo;
import com.zony.app.respository.FileInfoDao;
import com.zony.app.service.FileInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class FileInfoServiceImpl implements FileInfoService {
    @Autowired
    private FileInfoDao fileInfoDao;

    @Override
    public List<FileInfo> selectAllFileInfo() {
        List<FileInfo> fileInfoList = fileInfoDao.findAll();
        return fileInfoList;
    }

    @Override
    public FileInfo seleteFileInfoById(String id) {
        FileInfo fileInfo = fileInfoDao.seleteFileInfoById(id);
        return fileInfo;
    }

    @Override
    public void insertFileInfo(FileInfo fileInfo) {
        fileInfoDao.save(fileInfo);
    }

    @Override
    public void deleteFileInfoById(String id) {
        fileInfoDao.deleteFileInfoById(id);
    }

    @Override
    public void updateFileInfo(FileInfo fileInfo) {
        fileInfoDao.updateFileInfo(fileInfo.getId(),fileInfo.getFileName(),fileInfo.getFilePath(),fileInfo.getFileSize(),fileInfo.getPage());
    }
}
8.创建controller层
package com.zony.app.controller;

import com.zony.app.entity.FileInfo;
import com.zony.app.service.FileInfoService;
import com.zony.app.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
*@Description 文件信息记录到数据库中
*@Param
*@Return
*@Author ChuXu
*@Date 2022/3/24
*@Time 17:47
*/
@RestController
@RequestMapping("/FileInfoController")
public class FileInfoController {

    private final static Logger log = LoggerFactory.getLogger(FileInfoController.class);

    @Autowired
    private FileInfoService fileInfoService;

    /**
    *@Description 向文件信息表中添加一条信息
    *@Param [variables]
    *@Return com.zony.app.util.Result
    *@Author ChuXu
    *@Date 2022/3/25
    *@Time 10:56
    */
    @RequestMapping(value = "/insertFileInfo", method = RequestMethod.POST)
    public Result insertFileInfo(@RequestBody Map<String, Object> variables) {
        Result result = new Result();

        FileInfo fileInfo = new FileInfo();
        fileInfo.setFileName((String) variables.get("fileName"));
        fileInfo.setFilePath((String) variables.get("filePath"));
        fileInfo.setFileSize((String) variables.get("fileSize"));
        fileInfo.setPage((String) variables.get("page"));

        fileInfoService.insertFileInfo(fileInfo);

        result.setCode(200);
        result.setMessage("success");
        return result;
    }

    /**
    *@Description 根据id删除文件信息
    *@Param [id]
    *@Return com.zony.app.util.Result
    *@Author ChuXu
    *@Date 2022/3/25
    *@Time 10:59
    */
    @RequestMapping(value = "/deleteFileInfoById", method = RequestMethod.POST)
    public Result deleteFileInfoById(@RequestParam(value = "id") String id) {
        Result result = new Result();

        fileInfoService.deleteFileInfoById(id);

        result.setCode(200);
        result.setMessage("success");
        return result;
    }

    /**
    *@Description 修改文件信息
    *@Param [variables]
    *@Return com.zony.app.util.Result
    *@Author ChuXu
    *@Date 2022/3/25
    *@Time 11:04
    */
    @RequestMapping(value = "/updateFileInfo", method = RequestMethod.POST)
    public Result updateFileInfo(@RequestBody Map<String, Object> variables) {
        Result result = new Result();

        FileInfo fileInfo = new FileInfo();
        fileInfo.setId((String) variables.get("id"));
        fileInfo.setFileName((String) variables.get("fileName"));
        fileInfo.setFilePath((String) variables.get("filePath"));
        fileInfo.setFileSize((String) variables.get("fileSize"));
        fileInfo.setPage((String) variables.get("page"));

        fileInfoService.updateFileInfo(fileInfo);

        result.setCode(200);
        result.setMessage("success");
        return result;
    }

    /**
    *@Description 查询单个文件信息
    *@Param [id]
    *@Return com.zony.app.util.Result
    *@Author ChuXu
    *@Date 2022/3/25
    *@Time 11:05
    */
    @RequestMapping(value = "/seleteFileInfoById", method = RequestMethod.POST)
    public Result seleteFileInfoById(@RequestParam(value = "id") String id) {
        Result result = new Result();

        FileInfo fileInfo = fileInfoService.seleteFileInfoById(id);

        result.setCode(200);
        result.setMessage("success");
        result.setData(fileInfo);
        return result;
    }

    /**
    *@Description 查询所有文件信息
    *@Param []
    *@Return com.zony.app.util.Result
    *@Author ChuXu
    *@Date 2022/3/25
    *@Time 11:07
    */
    @RequestMapping(value = "/selectAllFileInfo", method = RequestMethod.POST)
    public Result selectAllFileInfo() {
        Result result = new Result();

        List<FileInfo> fileInfoList = fileInfoService.selectAllFileInfo();

        result.setCode(200);
        result.setMessage("success");
        result.setData(fileInfoList);
        return result;
    }
}

十一、controller层传参

1.map集合

一般用来传递实体类的JSON,使用postman传参直接传递一个JSON至后端。

@RequestBody Map<String, Object> variables
2.单个参数

一般用来传递单个参数,如人员的ID等。

使用postman传参直接在param中添加key,value即可。

@RequestParam(value = "id") String id

@RequestBody和@RequestParam的作用都是用来将前端传递过来的参数,直接绑定到后端controller控制器设置的参数中,区别在于:

@RequestBody限定了前端传递的参数必须为JSON格式,并且前端不能使用GET方式提交数据,而是使用POST方式提交,而且@RequestBody只能有一个。

@RequestParam用于接收url中key-value传递的参数,通常用于GET请求,POST请求也可以使用,可以有很多个。

3.文件流

传递文件流,后台一般用MultipartFile类接收,postman设置好后直接选择本地文件即可。

postman:Body–>form-data–>添加key,value即可,key类型选择file。

@RequestPart(name = "file") MultipartFile file

十一、controller层传参

1.map集合

一般用来传递实体类的JSON,使用postman传参直接传递一个JSON至后端。

@RequestBody Map<String, Object> variables
2.单个参数

一般用来传递单个参数,如人员的ID等。

使用postman传参直接在param中添加key,value即可。

@RequestParam(value = "id") String id

@RequestBody和@RequestParam的作用都是用来将前端传递过来的参数,直接绑定到后端controller控制器设置的参数中,区别在于:

@RequestBody限定了前端传递的参数必须为JSON格式,并且前端不能使用GET方式提交数据,而是使用POST方式提交,而且@RequestBody只能有一个。

@RequestParam用于接收url中key-value传递的参数,通常用于GET请求,POST请求也可以使用,可以有很多个。

3.文件流

传递文件流,后台一般用MultipartFile类接收,postman设置好后直接选择本地文件即可。

postman:Body–>form-data–>添加key,value即可,key类型选择file。

@RequestPart(name = "file") MultipartFile file
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值