项目总结(一)

该文总结了一个视频办理系统的开发过程,涉及SpringBoot项目结构设计,数据库表字段设计,依赖配置,如Redis、MyBatis-Plus等。实现了用户注册登录(MD5加密)、退出,头像上传,日志功能等,并利用Shiro和JWT进行权限管理。项目打包为war,部署在Tomcat上。
摘要由CSDN通过智能技术生成

最近刚结束视频办理系统1.0的项目,做个大致总结。

在本项目中,我参与了数据库表字段设计、后台搭建、打包部署等工作。

主要对后台搭建以及编写接口使用到的方法等内容进行总结。

1、创建一个springboot项目,设计包结构。共6个部分,分别是:config配置包、controller控制器交互类、entity实体类、mapper数据库映射类、service和serviceImpl业务逻辑实现层、utils通用工具包。

 

2、在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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>videoProcessing</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>videoProcessing</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>


        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.3.5.RELEASE</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!--fileupload-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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


        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>

        <!--devtools-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <!--生产配置元数据-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!--shiro-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <!--jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.2.0</version>
        </dependency>

        <!--aspect-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.4</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.2</version>
        </dependency>

        <!--lang-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.7</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.15</version>
        </dependency>

        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!--swagger-ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!--阿里云 sms sdk 依赖-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>alibabacloud-dysmsapi20170525</artifactId>
            <version>2.0.23</version>
        </dependency>


        <!--jacob-1.18-M2-->
        <dependency>
            <groupId>com.hynnet</groupId>
            <artifactId>jacob</artifactId>
            <version>1.18</version>
        </dependency>

        <!--swt-->
        <dependency>
            <groupId>org.eclipse</groupId>
            <artifactId>swt</artifactId>
            <version>3.3.0-v3346</version>
        </dependency>


        <!-- rsa工具  -->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.52</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.52</version>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>

        <!-- 添加访问静态资源文件 -->
        <!-- 代码的作用是让src/main/webapp在编译的时候在resoureces路径下也生成webapp的文件 -->
        <resources>
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

    </build>

</project>

3、在application.properties中配置相关信息

server.port=9080

#spring.servlet.multipart.max-file-size=10240MB
#uploadImgPath = D\:\\threevr\\pictures\\

spring.web.resources.static-locations= classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/video_processing?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.global-config.db-config.id-type=auto


spring.redis.database=6
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0
spring.redis.lettuce.shutdown-timeout=100ms

spring.jackson.time-zone=GMT+8
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

4、业务功能模块

(1)用户注册、登录

  • 注册模块:使用MD5加密加盐,将用户名、密码等信息存入数据库。
  • 登录模块:使用shiro+jwt+redis生成token校验,在用户登录时保存token信息,并实现用户在注册时使用的MD5加密加盐对应解密,实现登录。

(2)用户退出

用户退出后,将redis中的token以及用户名信息删除。(此功能已开发,前端暂未调用,无法检验是否正确)

(3)获取用户信息

(4)修改用户密码

此功能也需要借助MD5工具

public R<?> modifyPwdByUser(@RequestParam(name = "userName")String userName,
                                @RequestParam(name = "password") String password,
                                @RequestParam(name = "salt") String salt){
        password = SaltMD5Util.generateSaltPassword(password);
        User user = new User();
        salt = SaltMD5Util.generateSaltPassword(user.getSalt());
        int modify = userService.modifyPwd(userName,password,salt);
        System.out.println("modify:"+modify);
        if (modify!=0){
            return R.OK("修改成功!");
        }else
            return R.error("修改失败,请重试!");
    }

(5)修改用户头像

public static final int AVATAR_MAX_SIZE = 10 *1024 * 1024;
    public static final List<String> AVATAR_TYPE = new ArrayList<>();
    static {
        AVATAR_TYPE.add("image/jpeg");
        AVATAR_TYPE.add("image/png");
        AVATAR_TYPE.add("image/bmp");
        AVATAR_TYPE.add("image/gif");
    }
    @ApiOperation(value = "修改用户头像")
    @PostMapping("/modifyImg")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName",value = "用户名称",paramType = "query",dataType = "string")
    })
    public void modifyImg(@RequestParam(value = "file")MultipartFile file, HttpServletRequest request, HttpServletResponse response){
        if (file.isEmpty()){
            R.error("文件为空");
        }
        if (file.getSize() > AVATAR_MAX_SIZE){
            R.error("文件超出限制");
        }
        String contentType = file.getContentType();
        if (!AVATAR_TYPE.contains(contentType)){
            R.error("文件类型不支持");
        }

        String url = request.getContextPath();
        System.out.println("url:"+url);
        String parent = request.getSession().getServletContext().getRealPath("/avatar/");
        File dir = new File(parent);
        if (!dir.exists()){
            dir.mkdirs();
        }
        String imgName = file.getOriginalFilename();

        System.out.println("parent:"+parent);
        File dest = new File(dir,imgName);
        try {
            file.transferTo(dest);
        }catch (IOException e){
            R.error("文件读写异常");
        }
        String userName = request.getParameter("userName");
        String imgUrl = parent + imgName;
        System.out.println("imgUrl:"+imgUrl);
        User user = new User();
        imgName = imgName.substring(0,imgName.lastIndexOf("."));
        System.out.println("imgName:"+imgName);
        //user.setAvatar(imgUrl);
        user.setAvatar(imgName);
        int modify = userService.ModifyImg(userName,imgName);
        if (modify!=0){
            R.OK("上传成功");
        }
    }

(6)根据网办中心获取业务

此功能使用到了string字符串的相关用法

// 字符串userName的内容是否等于“网办中心”
"网办中心".equals(userName)

// 字符串userName的内容是否包括“网办中心”
userName.contains("网办中心")

(7)提交日志信息

此功能需要的是一个请求体,使用注解@RequestBody。在存入数据库的过程中,有几个string类型的字段需要从10进制转换成16进制,并返回16进制字符串。

//StringUtils.leftPad(Integer.toHexString(要转换的值),转换长度,转换后的长度不足,则头部补0)

List<BusinessForm> list = new ArrayList<>();
list = businessMapper.selectList(qw);
String businessId = StringUtils.leftPad(Integer.toHexString(list.get(0).getId()), 3, "0");

(8)分页查询日志

此功能有个使用自带分页查询,有个问题就是总数为0,在这里只能通过getRecords().size()来获取了。

@ApiOperation(value = "pageLogOld",notes = "根据条件获取日志信息")
    @PostMapping("/pageLogOld")
    //@RequiresAuthentication
    public R<?> pageLogOld(@RequestBody JSONObject jsonObject) {

        //Page<MatterLog> page = matterLogService.pageLogOld(jsonObject);
        String matterCode = jsonObject.getString("matterCode");
        String businessName = jsonObject.getString("businessName");
        String networkCenter = jsonObject.getString("networkCenter");
        String customName = jsonObject.getString("customName");
        String applyName = jsonObject.getString("applyName");
        String startTime = jsonObject.getString("startTime");
        String endTime = jsonObject.getString("endTime");
        QueryWrapper<MatterLog> qw = new QueryWrapper<>();
        if (matterCode!=null && (!"".equals(matterCode))){
            qw.eq("matter_code",matterCode);
        }
        if (businessName!=null && (!"".equals(businessName))){
            qw.eq("business_name",businessName);
        }
        if (networkCenter!=null && (!"".equals(networkCenter))){
            qw.eq("network_center",networkCenter);
        }
        if (customName!=null && (!"".equals(customName))){
            qw.eq("custom_name",customName);
        }
        if (applyName!=null && (!"".equals(applyName))){
            qw.eq("apply_name",applyName);
        }
        if (startTime!=null && (!"".equals(startTime))){
            qw.ge("create_time",startTime);
        }
        if (endTime!=null && (!"".equals(endTime))){
            qw.le("create_time",endTime);
        }
        //当前页数
        Long pageNum = Long.valueOf(String.valueOf(jsonObject.get("pageNum")));
        //每页显示数
        Long pageSize = Long.valueOf(String.valueOf(jsonObject.get("pageSize")));
        //进行分页查询-可跟条件
        Page<MatterLog> urf = matterLogmapper.selectPage(new Page<>(pageNum, pageSize), qw);
        //System.out.println("urf:"+urf);
        return R.OK(""+urf.getRecords().size(),urf);
    }

5、配置类

(1)shiro+jwt+redis生成token,完成登录校验。(可以看之前的学习笔记二)

(2)统一返回接口格式以及返回情况的枚举类

import lombok.Data;

import java.io.Serializable;

@Data
public class R<T> implements Serializable {

    private static final long serialVersionUID = 1l;

    //成功标志
    private Boolean success=true;
    //返回代码
    private Integer code;
    //返回处理消息
    private String message;
    //返回数据对象 data
    private T data;
    //时间戳
    private long timestamp = System.currentTimeMillis();

    public R(){}

    public R<T> success(String message) {
        this.message = message;
        this.code = 200;
        this.success = true;
        return this;
    }

    public static R<Object> ok(){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(ResultEnum.SUCCESS.getMessage());
        return r;
    }

    public static R<Object> ok(String msg){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(msg);
        return r;
    }

    public static R<Object> ok(Object data){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(ResultEnum.SUCCESS.getMessage());
        r.setData(data);
        return r;
    }

    public static<T> R<T> OK(){
        R<T> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(ResultEnum.SUCCESS.getMessage());
        return r;
    }

    public static<T> R<T> OK(T data){
        R<T> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(ResultEnum.SUCCESS.getMessage());
        r.setData(data);
        return r;
    }

    public static<T> R<T> OK(String msg,T data){
        R<T> r = new R<>();
        r.setSuccess(ResultEnum.SUCCESS.getSuccess());
        r.setCode(ResultEnum.SUCCESS.getCode());
        r.setMessage(msg);
        r.setData(data);
        return r;
    }

    /**
     * 请求失败
     */
    public static R<Object> error(){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.FAILED.getSuccess());
        r.setCode(ResultEnum.FAILED.getCode());
        r.setMessage(ResultEnum.FAILED.getMessage());
        return r;
    }

    public static R<Object> error(String msg){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.FAILED.getSuccess());
        r.setCode(ResultEnum.FAILED.getCode());
        r.setMessage(msg);
        return r;
    }

    public R<T> error500(String message) {
        this.message = message;
        this.code = 500;
        this.success = false;
        return this;
    }

    /**
     * 请求无权限
     */
    public static R<Object> unanthorized(){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.UNAUTHORIZED.getSuccess());
        r.setCode(ResultEnum.UNAUTHORIZED.getCode());
        r.setMessage(ResultEnum.UNAUTHORIZED.getMessage());
        return r;
    }

    /**
     * 请求无权限
     */
    public static R<Object> unanthorized(String message){
        R<Object> r = new R<>();
        r.setSuccess(ResultEnum.UNAUTHORIZED.getSuccess());
        r.setCode(ResultEnum.UNAUTHORIZED.getCode());
        r.setMessage(message);
        return r;
    }

    public R<T> setResult(ResultEnum resultEnum){
        R<T> r = new R<>();
        r.setSuccess(resultEnum.getSuccess());
        r.setCode(resultEnum.getCode());
        r.setMessage(resultEnum.getMessage());
        return r;
    }

    public R<T> success(Boolean status){
        this.setSuccess(status);
        return this;
    }

    public R<T> code(Integer code){
        this.setCode(code);
        return this;
    }

    public R<T> message(String message){
        this.setMessage(message);
        return this;
    }
}
import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
public enum ResultEnum {
    SUCCESS(true,200,"操作成功"),
    FAILED(false,300,"操作失败"),
    NO_OPERATOR_AUTH(false,301,"无操作权限"),
    DATA_ERROR(false,302,"数据错误"),
    DATA_NO_EXIST(false,303,"数据不存在"),
    UNAUTHORIZED(false,401,"用户认证失败");

    private final Boolean success;
    private final Integer code;
    private final String message;

    ResultEnum(Boolean success,Integer code,String message){
        this.success=success;
        this.code=code;
        this.message=message;
    }
}

(3)swagger配置

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

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(this.apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.videoprocessing.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("videoProcessing APIs")
                .description("API")
                .termsOfServiceUrl("url")
                .version("1.0")
                .build();
    }
}

6、通用工具包utils

(1)JwtUtil(可看之前的学习笔记二)

(2)oConvertUtils(定义随机数)

import lombok.extern.slf4j.Slf4j;

import java.util.Random;

@Slf4j
public class oConvertUtils {

    /**
     * 随机数
     * @param place 定义随机数的位数
     */
    public static String randomGen(int place) {
        String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789";
        StringBuffer sb = new StringBuffer();
        Random rd = new Random();
        for(int i=0;i<place;i++) {
            sb.append(base.charAt(rd.nextInt(base.length())));
        }
        return sb.toString();
    }
}

(3)RedisUtil(可看之前的学习笔记二)

(4)SaltMD5Util(MD5加密加盐)

import org.apache.commons.codec.binary.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

public class SaltMD5Util {

    /**
     * @Description 生成普通的MD5密码
     */
    public static String MD5(String input){
        MessageDigest md5 = null;
        try {
            //生成普通的MD5密码
            md5 = MessageDigest.getInstance("MD5");
        }catch (NoSuchAlgorithmException e){
            return "check jdk";
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
        char[] charArray = input.toCharArray();
        byte[] byteArray = new byte[charArray.length];
        for (int i = 0; i < charArray.length; i++)
            byteArray[i] = (byte) charArray[i];
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++){
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16)
                hexValue.append("0");
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }

    /**
     * @Description 生成盐和加盐后的MD5码,并将盐混入到MD5码中,对MD5密码进行加强
     */
    public static String generateSaltPassword(String password) {
        Random random = new Random();
        //生成一个16位的随机数,即盐
        /**
         * 此处的盐也可以定义成一个系统复杂的常量,而不是非要靠随机数,两种方式均可
         * 盐加密 : salt的字符串是随意打的,目的是把MD5加密后的再次加密变得复杂
         */
        StringBuilder stringBuilder = new StringBuilder(16);
        stringBuilder.append(random.nextInt(99999999)).append(random.nextInt(99999999));
        int len = stringBuilder.length();
        if (len < 16) {
            for (int i = 0; i< 16 - len; i++){
                stringBuilder.append("0");
            }
        }
        //生成盐
        String salt = stringBuilder.toString();
        //将盐加到明文中,生成新的MD5码
        password = md5Hex(password + salt);
        //将盐混到新生成的MD5码中,方便后期校验明文和密文
        char[] cs = new char[48];
        for (int i = 0; i < 48; i+= 3){
            cs[i] = password.charAt(i / 3 * 2);
            char c = salt.charAt(i / 3);
            cs[i + 1] = c;
            cs[i + 2] = password.charAt(i / 3 * 2 + 1);
        }
        return new String(cs);
    }

    /**
     * @Description 验证明文和加盐后的MD5码是否匹配
     */
    public static boolean verifySaltPassword(String password,String md5){
        //先从MD5码中取出之前加的盐和加盐后生成的MD5码
        char[] cs1 = new char[32];
        char[] cs2 = new char[16];
        for (int i = 0; i < 48; i += 3){
            cs1[i / 3 * 2] = md5.charAt(i);
            cs1[i / 3 * 2 + 1] = md5.charAt(i + 2);
            cs2[i / 3] = md5.charAt(i + 1);
        }
        String salt = new String(cs2);
        //比较二者是否相同
        return md5Hex(password+salt).equals(new String(cs1));
    }

    /**
     * @Description 生成MD5密码
     */
    private static String md5Hex(String src) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] bs = md5.digest(src.getBytes());
            return new String(new Hex().encode(bs));
        }catch (Exception e){
            return null;
        }
    }

    public static void main(String args[]){
        //原密码
        String password  = "123456";
        System.out.println("明文密码: "+password);
        //MD5加密后的密码
        String MD5Password = MD5(password);
        System.out.println("普通MD5加密密码: "+MD5Password);
        //获取加盐后的MD5密码
        String SaltPassword = generateSaltPassword(password);
        System.out.println("加盐后的密码: "+SaltPassword);
        System.out.println("加盐后的密码和明文密码是否是同一字符串: "+verifySaltPassword(password,SaltPassword));
    }
}

7、项目打包部署

(1)项目打包形式是war包。在pom.xml内定义war形式,在右侧Maven栏中,找到项目的生命周期,依次双击“clean”、“package”;在左侧项目栏中可看到target包。

(2)部署:放于tomcat9.0.50的webapp文件夹内,修改server.xml文件内容,启动“bin”目录下的“startup.bat”。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值