项目相关依赖在文末
一.连接数据库
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>