从零开始项目搭建(数据库连接+拦截器+swagger+异常抛出)

2 篇文章 0 订阅
2 篇文章 0 订阅

项目相关依赖在文末

一.连接数据库

1.启动启动类,是否构建成功

2.写一个hellow接口使用端口连接测试一下

@RestController
public class Helloword {
    @RequestMapping("/helloWord")
    public String helloWord(){
        return "helloWord";
    }
}

若成功则下一步

3.连接数据库

#连接端口
server.port=9000
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong&allowMultiQueries=true
#spring.datasource.url=jdbc:mysql://localhost/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong&allowMultiQueries=true
spring.datasource.username=数据库账号
spring.datasource.password=数据库密码

二.创建控制层,service层,entity层,mapper层(可以使用代码生成器快速生成)

1.controller层

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;
    @GetMapping(value = "/login")
    public String login(){
        User byId = userService.getById( 1 );
        return byId.getName();
    }
}

2.实体层

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value = "User对象", description = "")
public class User {
    private static final long serialVersionUID = 1L;
    private Long id;
    private String name;
    private String card;
    private String password;
    private String avater;
    private String age;
    private String version;
    private String email;
    private Integer deleted;
    private Date create_time;
    private Date updateTime;
}

3.service层

在这里插入图片描述

public interface UserService extends IService<User> {
}

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

4.mapper层

在这里插入图片描述


@Mapper
public interface UserMapper extends BaseMapper<User> {
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.txyunOss.mapper.UserMapper">
</mapper>

重新启动连接端口是否接收数据
顺利则数据库连接成功

二.拦截器

系统配置项,常量

#拦截器通行地址
handler-address=/user,/helloWord
#token
token.privateKey='fdasfgdsagaxgsregdfdjyghjfhebfdgwe45ygrfbsdfshfdsag'
token.yangToken=1000000
token.oldToken=3000000

token拦截器


@Configuration
public class AuthWebMvcConfig  implements WebMvcConfigurer {
	//将拦截器放行地址放到系统常量里去
    @Value( value = "${handler-address}")
    private String handlerAddress;
    @Autowired
    AuthHandlerInterceptor authHandlerInterceptor;
    /**
     * 给接口都配置拦截器,拦截转向到 authHandlerInterceptor
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//将配置项里的地址进行划分和添加字符
        String handlerAddressReplace = handlerAddress.replace( ",", "/**," );
        handlerAddressReplace = handlerAddressReplace +"/**";
        String[] handlerAddressReplaceSplit= handlerAddressReplace.split( "," );
        
        registry.addInterceptor(authHandlerInterceptor)
                .addPathPatterns("/**")
                //放行地址
                .excludePathPatterns(handlerAddressReplaceSplit)
                //放行swagger
                .excludePathPatterns("/swagger-resources/**",
                        "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }
}

token验证+刷新token

@Slf4j
@Component
public class AuthHandlerInterceptor implements HandlerInterceptor {

    @Autowired
    TokenUtil tokenUtil;
    @Value("${token.privateKey}")
    private String privateKey;
    @Value("${token.yangToken}")
    private Long yangToken;
    @Value("${token.oldToken}")
    private Long oldToken;


    /**
     * 权限认证的拦截操作.
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        log.info("=======进入拦截器========");
        if (HttpMethod.OPTIONS.toString().equals(httpServletRequest.getMethod())) {
            System.out.println("OPTIONS请求,放行");
            return true;
        }
        // 如果不是映射到方法直接通过,可以访问资源.
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        //为空就返回错误
        String token = httpServletRequest.getHeader("x-token");
        if (null == token || "".equals(token.trim())) {
            return false;
        }
        log.info("==============token:" + token);
        Map<String, String> map = tokenUtil.parseToken(token);
        String userId = map.get("roles");
        String userRole = map.get("name");
        long timeOfUse = System.currentTimeMillis() - Long.parseLong(map.get("timeStamp"));
        //1.判断 token 是否过期
        //年轻 token
        if (timeOfUse < yangToken) {
            log.info("年轻 token");
        }
        //老年 token 就刷新 token
        else if (timeOfUse >= yangToken && timeOfUse < oldToken) {
            httpServletResponse.setHeader("token",tokenUtil.getToken(userId,userRole));
        }
        //过期 token 就返回 token 无效.
        else {
//            throw new TokenAuthExpircedException();
        }
        //2.角色匹配.
        if ("user".equals(userRole)) {
            log.info("========user账户============");
            return true;
        }
        if ("admin".equals(userRole)) {
            log.info("========admin账户============");
            return true;
        }
        return true;
    }
}

@Component
public class TokenUtil {
    @Value("${token.privateKey}")
    private String privateKey;

    public String getToken(String roles,String name){
        String token = JWT
                .create()
                .withClaim("roles",roles)
                .withClaim("name", name)
                .withClaim("timeStamp", System.currentTimeMillis())
                .sign(Algorithm.HMAC256(privateKey));
        return token;
    }

    public Map<String,String> parseToken(String token){
        HashMap<String,String> map = new HashMap<>();
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(privateKey))
                .build().verify(token);

        Claim userId = decodedJWT.getClaim("roles");
        Claim userRole = decodedJWT.getClaim("name");
        Claim timeStamp = decodedJWT.getClaim("timeStamp");
        map.put("roles", userId.asString());
        map.put("name", userRole.asString());
        map.put("timeStamp", timeStamp.asLong().toString());
        return map;
    }
}

3.整合swagger

一定不要忘记配置swagger的扫描路径
在启动类上加上swagger注解
在记得在实体类上还有接口上加上注解说明
在这里插入图片描述
在这里插入图片描述

//swagger的配置

@Configuration//
@EnableSwagger2//swagger注解
public class SwaggerConfig {

    @Bean
    public Docket createRestApi() {
        return new Docket( DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //扫描swagger路径
                .apis( RequestHandlerSelectors.basePackage("com.example"))
                .paths( PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("swagger-bootstrap-ui RESTful APIs")
                .description("swagger-bootstrap-ui")
                .termsOfServiceUrl("http://localhost:8999/")
                .version("1.0")
                .build();
    }
}

//启动类
@EnableScheduling  //加入定时器
@EnableSwagger2
@EnableSwaggerBootstrapUI
@SpringBootApplication
public class TxyunOssApplication {

    public static void main(String[] args) {
        SpringApplication.run( TxyunOssApplication.class, args );
    }

}

配置结束后访问:http://localhost:9000/doc.html#/
成功返回的既是配置成功(在拦截器上记得例外掉swagger地址)
在这里插入图片描述

四.几个工具类(通用成功失败返回+异常抛出)

1.统一返回结果的类


//统一返回结果的类
@Data
public class R {

    @ApiModelProperty(value = "是否成功")
    private Boolean success;

    @ApiModelProperty(value = "返回码")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String message;

    @ApiModelProperty(value = "返回数据")
    private Map<String, Object> data = new HashMap<String, Object>();

    //把构造方法私有化
    private R() {

    }

    //成功的静态方法
    public static R ok() {
        R r = new R();
        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("成功");
        return r;
    }

    //失败的静态方法
    public static R error() {
        R r = new R();
        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMessage("失败");
        return r;
    }

    public R success(Boolean success) {
        this.setSuccess(success);
        return this;
    }

    public R message(String message) {
        this.setMessage(message);
        return this;
    }

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

    public R data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public R data(Map<String, Object> map) {
        this.setData(map);
        return this;
    }
}

public interface ResultCode {
    public static Integer SUCCESS = 20000;//成功
    public static Integer ERROR = 20001;//失败
}

调用接口成功返回
在这里插入图片描述

异常抛出


@Slf4j
@ControllerAdvice
public class ExceptionHandlerUtil {
    //全局异常处理
    @ExceptionHandler(Exception.class)
    @ResponseBody//返回数据
    public R error(Exception e) {
        e.printStackTrace();
        return R.error().message(String.valueOf(e));
    }

    //    特殊异常处理
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody//返回数据
    public R error(ArithmeticException e) {
        e.printStackTrace();
        return R.error().message("执行了ArithmeticException异常处理");
    }

    //    自定义异常处理
    @ExceptionHandler(ExceptionUtil.class)
    @ResponseBody//返回数据
    public R error(ExceptionUtil e) {
        e.printStackTrace();
        return R.error().code(e.getCode()).message(e.getMsg());
    }

    //    自定义异常处理
    @ExceptionHandler(TokenAuthExpircedException.class)
    @ResponseBody
    public String tokenExpiredExceptionHandler(){
        log.warn("用户 token 过期");
        return "用户 token 过期";
    }
    
@Data
@AllArgsConstructor //生成有参数的构造方法
@NoArgsConstructor //生成无参构造
public class ExceptionUtil extends RuntimeException {
    private Integer code;//状态码
    private String msg;//异常信息
}

接口调用
在这里插入图片描述
在这里插入图片描述

有结果返回即是成功

以上是从零开始简单的搭建项目框架的简单过程

在下一篇里准备加入oss图片管理功能(目标是做一个相册管理的项目,并部署到服务器上)

最后附上代码结构图
在这里插入图片描述

添加依赖(部分可能多余)

版本号
    <properties>
        <java.version>1.8</java.version>
        <java.version>1.8</java.version>
        <guli.version>0.0.1-SNAPSHOT</guli.version>
        <mybatis-plus.version>3.0.5</mybatis-plus.version>
        <velocity.version>2.0</velocity.version>
        <swagger.version>2.7.0</swagger.version>
        <aliyun.oss.version>2.5.0</aliyun.oss.version>
        <jodatime.version>2.10.1</jodatime.version>
        <poi.version>3.17</poi.version>
        <commons-fileupload.version>1.3.1</commons-fileupload.version>
        <commons-io.version>2.6</commons-io.version>
        <httpclient.version>4.5.1</httpclient.version>
        <jwt.version>0.9.0</jwt.version>
        <aliyun-java-sdk-core.version>4.0.3</aliyun-java-sdk-core.version>
        <aliyun-sdk-oss.version>2.5.0</aliyun-sdk-oss.version>
        <aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version>
        <aliyun-java-vod-upload.version>1.4.11</aliyun-java-vod-upload.version>
        <aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version>
        <fastjson.version>1.2.28</fastjson.version>
        <gson.version>2.8.2</gson.version>
        <json.version>20171018</json.version>
        <commons-dbutils.version>1.2</commons-dbutils.version>
        <canal.client.version>1.1.0</canal.client.version>
        <docker.image.prefix>zx</docker.image.prefix>
        <cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
    </properties>
    
    依赖名称
        <!--Spring Cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!--mybatis-plus 持久层-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>${velocity.version}</version>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <!--swagger ui-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <!--aliyunOSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>${aliyun.oss.version}</version>
        </dependency>
        <!--日期时间工具-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${jodatime.version}</version>
        </dependency>
        <!--xls-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <!--xlsx-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.version}</version>
        </dependency>
        <!--文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version>
        </dependency>
        <!--commons-io-->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io.version}</version>
        </dependency>
        <!--httpclient-->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>${gson.version}</version>
        </dependency>
        <!-- JWT -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jwt.version}</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>
        <!--aliyun-->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>${aliyun-java-sdk-core.version}</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-vod</artifactId>
            <version>${aliyun-java-sdk-vod.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>${json.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>${commons-dbutils.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.otter</groupId>
            <artifactId>canal.client</artifactId>
            <version>${canal.client.version}</version>
        </dependency>

        <dependency>
            <groupId>com.qcloud</groupId>
            <artifactId>cos_api</artifactId>
            <version>5.6.54</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.2.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.5.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
       //swagger配置
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.6</version>
        </dependency>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值