Spring Boot + Vue +Three.js综合案例(中)--后端开发

后端开发----Spring Boot +MyBatis(MySQL)


一、项目的搭建

使用IDEA编辑器创建好项目,具体项目结构如图
在这里插入图片描述

  • pom.xml(Maven管理器),添加好对应依赖
<?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>

    <!--继承Spring Boot的父级项目的依赖-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot_vue</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_vue</name>
    <description>Demo project for Spring Boot</description>
    <!--打war包-->
    <packaging>war</packaging>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--springboot开发web项目的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--测试的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--springboot开发自动热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!--JSON依赖包-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.2.3</version>
            <classifier>jdk15</classifier>
        </dependency>

        <!--加载Mybatis整合springboot-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>

        <!--Mysql的jdbc驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>

        <!--java-jjwt依赖-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>


    </dependencies>

    <build>

        <plugins>
            <!--springboot项目编译打包插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!--mybatis代码自动生成插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>GeneratorMapper.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>

        <!--编译文件所在目录、类型,到指定位置-->
        <resources>
            <!--编译XML文件到class目录-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!--所有配置文件编译到class目录-->
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>

    </build>

</project>

  • GeneratorMapper.xml,添加数据库生成的信息,使用Mybatis代码自动生成插件,生成数据库中对应的model类和mapper类
<?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>

    <!--需要修改,jar包位置-->
    <!-- 指定连接数据库的JDBC驱动jar包所在位置,指定到本机的完整路径 -->
    <classPathEntry location="D:\Code\Java\jar\mysql-connector-java-5.1.13-bin.jar" />

    <!--配置tbale表信息内容体,targetRuntime指定采用MyBatis3的版本,一个数据库一个context-->
    <context id="tables" targetRuntime="MyBatis3">

        <!--抑制生成注释,由于生成的注释都是英文的,可以不生成-->
        <commentGenerator>
            <property name="suppressAllComments" value="true"></property>
        </commentGenerator>

        <!--需要修改,账户密码-->
        <!--配置数据库连接信息,指定数据库名-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/dbtest"
                        userId="root" password="admin">
        </jdbcConnection>

        <!--需要修改,下列相关包名-->
        <!--生成model类,targetPackage指定model类的包名,targetProject指定生成的model放在IDEA的哪个工程下面-->
        <javaModelGenerator targetPackage="com.example.springboot_vue.model" targetProject="src/main/java">
            <!-- 是否在当前路径下新加一层schema,eg:false路径com.example.springboot.model, true:com.example.springboot.model.[schemaName] -->
            <property name="enableSubPackages" value="false"></property>
            <!-- 是否针对string类型的字段在set的时候进行trim调用 -->
            <property name="trimStrings" value="false"></property>
        </javaModelGenerator>

        <!--需要修改,下列相关包名-->
        <!--生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名,targetProject指定生成的mapper.xml放在什么位置-->
        <sqlMapGenerator targetPackage="com.example.springboot_vue.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"></property>
        </sqlMapGenerator>

        <!--需要修改,下列相关包名-->
        <!--生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名,targetProject指定生成的Mapper接口放在eclipse的哪个工程下面-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.springboot_vue.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"></property>
        </javaClientGenerator>

        <!--需要修改,表名-->
        <!--数据库表名及对应生成的java模型名-->
        <!-- schema即为数据库名 tableName为对应的数据库表 domainObjectName是要生成的实体类
        enable*ByExample 是否生成 example类   -->

        <table tableName="userinfo"
               domainObjectName="UserInfo"    enableCountByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               enableUpdateByExample="false" selectByExampleQueryId="false">
        </table>

    </context>

</generatorConfiguration>
  • application.properties,项目属性配置
#项目描述
info.project-url=http://127.0.0.1:8089/springboot_vue/
info.author=lingfengzi
info.version=1.0.0

#设置项目路径
server.servlet.context-path=/springboot_vue
#设置项目访问端口号
server.port=8089

#配置数据库连接信息
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dbtest?useUnicode=true&characterEncoding=utf-8&useSSL=false


二、代码编辑

  1. 设置java web token生成工具,utils/JwtUtil.java。
package com.example.springboot_vue.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import net.sf.json.JSONObject;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

public class JwtUtil {

    private static final long EXPIRATION_TIME = (long)(168*3600*1000); // 有效时间:7天 24h*7=168h,转换为时间戳单位
    private static final String SECRET = "secret";//  密钥

    //解析
    public static JSONObject parseJWT(String jsonWebToken) {
        try{
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
                    .parseClaimsJws(jsonWebToken).getBody();

            //System.out.println(claims);

            JSONObject json=new JSONObject();
            //json.put("userId",claims.get("userId"));
            //json.put("password",claims.get("password"));
            json.put("nbf",claims.getNotBefore().getTime());
            json.put("exp",claims.getExpiration().getTime());
            return json;
        }catch (Exception e){
            return  null;
        }
    }

    //生成
    public static String createJWT(String userId, String password) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        //当前时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //添加构成JWT的参数
        JwtBuilder jwtBuilder = Jwts.builder().setHeaderParam("type", "JWT")
                .claim("userId", userId)
                .claim("password", password)
                .signWith(signatureAlgorithm, signingKey);

        //添加Token过期时间
        long expMillis = nowMillis + EXPIRATION_TIME;
        Date exp = new Date(expMillis);
        jwtBuilder.setExpiration(exp).setNotBefore(now);

        //返回生成的JWT字符串
        return jwtBuilder.compact();
    }


    public static void main(String[] args){
        String token = JwtUtil.createJWT("10001", "123456");
        System.out.println(token);

        JSONObject json=JwtUtil.parseJWT(token);
        System.out.println(json.toString());
    }

}

  1. 在service包下设置数据库服务功能接口以及实现,然后在mapper下写入调用数据库的语句;
    service/impl/UserInfoServiceImpl .java
package com.example.springboot_vue.service.impl;

import com.example.springboot_vue.mapper.UserInfoMapper;
import com.example.springboot_vue.model.UserInfo;
import com.example.springboot_vue.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Autowired
    UserInfoMapper userInfoMapper;

    @Override
    public UserInfo loginCheck(String username, String password) {
        return userInfoMapper.loginCheck(username,password);
    }

    @Override
    public int updateUserToken(String username, String token) {
        return userInfoMapper.updateUserToken(username,token);
    }

    @Override
    public UserInfo selectByToken(String token) {
        return userInfoMapper.selectByToken(token);
    }
}

mapper/UserInfoMapper.xml

  <!--验证登录,并取得用户信息-->
  <select id="loginCheck" parameterType="String" resultMap="BaseResultMap">
    select
    id,username,password
    from userinfo
    where username=#{username,jdbcType=VARCHAR}
    and password = #{password,jdbcType=VARCHAR}
  </select>
<!--更新用户令牌-->
  <update id="updateUserToken" parameterType="String">
    update userinfo
    set
      token = #{token,jdbcType=VARCHAR}
    where username=#{username,jdbcType=VARCHAR}
  </update>
  <!--通过令牌换取用户信息-->
  <select id="selectByToken" parameterType="String" resultMap="BaseResultMap">
    select
    id,username,password
    from userinfo
    where token = #{token,jdbcType=VARCHAR}
  </select>
  1. 登录请求控制器,controller/LoginController.java
package com.example.springboot_vue.controller;

import com.example.springboot_vue.model.UserInfo;
import com.example.springboot_vue.service.UserInfoService;
import com.example.springboot_vue.utils.JwtUtil;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

@Controller
public class LoginController {
    @Autowired
    UserInfoService userInfoService;

    @RequestMapping("/loginCheck")
    public @ResponseBody JSONObject loginCheck(@RequestBody JSONObject data, HttpServletResponse response){
        JSONObject json=new JSONObject();
        String username=data.getString("username");
        String password=data.getString("password");
        UserInfo userInfo= userInfoService.loginCheck(username,password);
        if(userInfo!= null){
            json.put("code",0);
            json.put("data",userInfo);
            json.put("msg","");

            String token= JwtUtil.createJWT(userInfo.getId().toString(),password);

            //更新存储令牌,一般存于redis中,示例存储在mysql
            userInfoService.updateUserToken(username,token);

            //从http头部设置token
            response.setHeader("authorization",token);
            // axios请求,跨域的情况下,这样设置才能从headers中拿到token
            response.setHeader("Access-Control-Expose-Headers", "authorization");
        }else{
            json.put("code",500);
            json.put("data",null);
            json.put("msg","用户名或密码错误");
        }
        return json;
    }

    @RequestMapping("/getUserInfo")
    public @ResponseBody JSONObject getUserInfo(HttpServletRequest request){
        String token=request.getHeader("authorization");
        JSONObject json=JwtUtil.parseJWT(token);

        long exp=Long.parseLong(json.getString("exp"));//过期时间
        long nbf=new Date().getTime();

        if(exp>nbf){
            UserInfo userInfo= userInfoService.selectByToken(token);
            if(userInfo !=null){
                json.put("code",0);
                json.put("data",userInfo);
                json.put("msg","");
            }else{
                json.put("code",500);
                json.put("data",null);
                json.put("msg","登录信息不存在,请重新登录");
            }
        }else{
            json.put("code",501);
            json.put("data",null);
            json.put("msg","登录信息已失效,请重新登录");
        }
        return json;
    }
}

  1. 在本地浏览时,前后端开了两个服务器,会存在浏览器跨域问题,所以要设置允许跨域
    config/WebConfig.java
package com.example.springboot_vue.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        //设置允许跨域的路径
        registry.addMapping("/**")
                //设置允许跨域请求的域名
                //**Credentials为true时,**Origin不能为星号,需为具体的ip地址【如果接口不带cookie,ip无需设成具体ip】
                .allowedOrigins("http://localhost:8080")
                //是否允许证书 不再默认开启
                .allowCredentials(true)
                //设置允许的方法
                .allowedMethods("*")
                //跨域允许时间
                .maxAge(3600);
    }
}

至此,Spring Boot +Vue,前后端分离项目已经基本完成,并且测试通信成功。
在这里插入图片描述


Spring Boot + Vue +Three.js综合案例(上)–前端开发

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值