springboot篇】十六. springboot整合shiro和swagger2实现前后分离

springboot整合shiro和swagger2实现前后分离

中国加油,武汉加油!

篇幅较长,配合右边目录观看

项目准备

  1. 创建springboot项目nz1904-springboot-08-shiro-swagger
  2. 加入Web的SpringWeb依赖和Lombox依赖
  3. 导相关依赖
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>druidartifactId>
        <version>1.1.0version>
    dependency>
    <dependency>
    	<groupId>com.alibabagroupId>
    	<artifactId>fastjsonartifactId>
    	<version>1.2.54version>
    dependency>
    
    <dependency>
    	<groupId>io.springfoxgroupId>
    	<artifactId>springfox-swagger2artifactId>
    	<version>2.7.0version>
    dependency>
    <dependency>
    	<groupId>io.springfoxgroupId>
    	<artifactId>springfox-swagger-uiartifactId>
    	<version>2.7.0version>
    dependency>
    
    <dependency>
    	<groupId>org.apache.shirogroupId>
    	<artifactId>shiro-springartifactId>
    	<version>1.3.2version>
    dependency>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-jdbcartifactId>
    dependency>
    
    <dependency>
        <groupId>org.mybatis.spring.bootgroupId>
        <artifactId>mybatis-spring-boot-starterartifactId>
        <version>2.1.1version>
    dependency>
    
    <dependency>
        <groupId>mysqlgroupId>
        <artifactId>mysql-connector-javaartifactId>
        <version>5.1.48version>
    dependency>
    

1. 扩展/配置

1.1 定义SwaggerConfig和ShiroConfig

package com.wpj.config;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
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;

@SpringBootConfiguration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket createApi(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.wpj.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("这里是springboot整合shiro和swagger前后分离的功能文档")
                .description("这里是nz1904-springboot-08-shiro-swagger测试用的")
                .version("v1.0")
                .build();
    }

}
package com.wpj.config;

import org.springframework.boot.SpringBootConfiguration;

@SpringBootConfiguration
public class ShiroConfig {
    // 暂时不注入组件
}

1.2 对原生Token对象进行扩展

package com.wpj.token;

import org.apache.shiro.authc.UsernamePasswordToken;

/**
 * 对原生的token对象进行拓展
 */
public class CustomToken extends UsernamePasswordToken {

    // 这个token是在认证通过之后  用户访问其他资源的时候 来进行你给身份识别的
    private String token;   // 用户身份唯一的标识

    public CustomToken(String token) {
        this.token = token;
    }

    @Override
    public Object getPrincipal() {
        return token;
    }
}

1.3 定义业务异常

package com.wpj.exception;

/**
 * 业务异常
 */
public class BusinessException extends RuntimeException {
    
    private int messageCode;
    
    private String defaultMessage;
    
    public BusinessException(int messageCode, String defaultMessage){
        super(defaultMessage);
        this.messageCode = messageCode;
        this.defaultMessage = defaultMessage;
    }

    public String getDefaultMessage() {
        return defaultMessage;
    }

    public int getMessageCode() {
        return messageCode;
    }
}

1.4 定义常量类

package com.wpj.constant;

public class Constant {

    public static final String REQ_TOKEN = "token";

}

1.5 定义请求返回的类和枚举和接口

package com.wpj.result;

import lombok.Data;

/**
 * 最终响应给前端数据的对象
 */
@Data
public class DataResult <T> {
    private int code;   //返回的码值
    private String msg; //返回的错误信息提示
    private T data;   //返回的数据

    //下面这一块是对构造器进行封装

    public DataResult(int code,T data){
       this.code=code;
       this.data=data;
       this.msg=null;
    }

    public DataResult(int code,String msg,T data){
          this.code=code;
          this.data=data;
          this.msg=msg;
    }

    public DataResult(int code,String msg){
        this.code=code;
        this.msg=msg;
    }

    public DataResult(){
        this.code=BaseResponseCode.SUCCESS.getCode();
        this.msg=BaseResponseCode.SUCCESS.getMsg();
        this.data=null;
    }

    public DataResult(T data){
        this.code=BaseResponseCode.SUCCESS.getCode();
        this.msg=BaseResponseCode.SUCCESS.getMsg();
        this.data=data;
    }

    public DataResult(ResponseCodeInterface responseCodeInterface){
         this.data=null;
         this.code=responseCodeInterface.getCode();
         this.msg=responseCodeInterface.getMsg();
    }

    public DataResult(ResponseCodeInterface responseCodeInterface,T data){
         this.data=data;
         this.code=responseCodeInterface.getCode();
         this.msg=responseCodeInterface.getMsg();
    }

    /**
     * 不带数据的返回
     * @param 
     * @return
     */
    public static <T>DataResult success(){
       return new DataResult();
    }

    /**
     * 带数据的返回
     * @param data
     * @param 
     * @return
     */
    public static <T>DataResult success(T data){
       return new DataResult(data);
    }

    /**
     * 自己给参数的问题
     * @param code
     * @param msg
     * @param data
     * @param 
     * @return
     */
    public static <T>DataResult getResult(int code,String msg,T data){
        return new <T>DataResult(code,msg,data);
    }
    
    /**
     * 自己给参数的问题
     * @param code
     * @param msg
     * @param 
     * @return
     */
    public static <T>DataResult getResult(int code,String msg){
        return new <T>DataResult(code,msg);
    }

    /**
     * 直接传递一个枚举进来
     * @param baseResponseCode
     * @param 
     * @return
     */
    public static <T>DataResult getResult(BaseResponseCode baseResponseCode){
        return new <T>DataResult(baseResponseCode);
    }
    
    /**
     * 直接传递一个枚举进来
     * @param baseResponseCode
     * @param 
     * @return
     */
    public static <T>DataResult getResult(BaseResponseCode baseResponseCode,T data){
        return new <T>DataResult(baseResponseCode,data);
    }
    
}
package com.wpj.result;

public enum BaseResponseCode implements ResponseCodeInterface{
    /**
     * 接下来就要和前端约束好所有的码值以及含义
     */
    SUCCESS(0,"操作成功"),
    SYSTEM_ERROR(5000001,"系统错误"),
    METHOD_INVALIDATE(4000001,"数据校验出错"),
    DATA_ERROR(4000002,"传入数据异常"),
    TOKEN_NOT_NULL(4010001,"用户认证异常");

    //整个构造函数
    BaseResponseCode(int code,String msg){
        this.code=code;
        this.msg=msg;
    }

    private int code;
    private String msg;

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }
}
package com.wpj.result;

/**
 * 返回码的一个接口
 */
public interface ResponseCodeInterface {
    /**
     * 返回的码的一个获取
     * @return
     */
    int getCode();

    /**
     * 返回消息的获取
     * @return
     */
    String getMsg();
}

1.6 自定义过滤器拦截请求

package com.wpj.filter;

import com.alibaba.fastjson.JSONObject;
import com.wpj.constant.Constant;
import com.wpj.exception.BusinessException;
import com.wpj.token.CustomToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * 对身份进行二次校验的时候就会进来这里
 */
public class CustomAccessControllerFilter extends AccessControlFilter {
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 校验身份
        try {
            // 获取token
            String token = request.getHeader(Constant.REQ_TOKEN);
            // 判断token是否为空
            if (StringUtils.isEmpty(token)) {
                // 身份非法
                throw new BusinessException(400001, "用户的请求token不能为空。");
            } else {
                // 封装token交给shiro去认证,查看是否合法
                CustomToken customToken = new CustomToken(token);
                // 用户第一次登陆并不会执行,是在认证成功之后访问其他资源的时候才执行
                // login最终会执行到Realm中的doGetAuthenticationInfo方法里
                getSubject(servletRequest, servletResponse).login(customToken);
            }
        } catch (BusinessException e) {
            // 返回json格式信息通知前端出问题了
            resultResponse(e.getMessageCode(), e.getDefaultMessage(), servletResponse);
        } catch (AuthenticationException e) {
            if(e.getCause() instanceof BusinessException) {
                // 将异常的实例进行转换
                BusinessException err = (BusinessException) e.getCause();
                resultResponse(err.getMessageCode(), err.getDefaultMessage(), servletResponse);
            } else {
                // 执行这里就说明这个异常是shiro返回的
                resultResponse(400001, "用户认证失败", servletResponse);
            }
        } catch (AuthorizationException e) {
            if(e.getCause() instanceof BusinessException) {
                // 将异常的实例进行转换
                BusinessException err = (BusinessException) e.getCause();
                resultResponse(err.getMessageCode(), err.getDefaultMessage(), servletResponse);
            } else {
                // 执行这里就说明这个异常是shiro返回的
                resultResponse(403001, "用户没有访问权限", servletResponse);
            }
        } catch (Exception e) { // 一些未考虑的异常
            if(e.getCause() instanceof BusinessException) {
                // 将异常的实例进行转换
                BusinessException err = (BusinessException) e.getCause();
                resultResponse(err.getMessageCode(), err.getDefaultMessage(), servletResponse);
            } else {
                // 执行这里就说明这个异常是shiro返回的
                resultResponse(500001, "系统出现异常", servletResponse);
            }
        }

        return true;
    }

    /**
     * 通知前端出错的信息
     * @param messageCode
     * @param defaultMessage
     * @param response
     */
    private void resultResponse(int messageCode, String defaultMessage, ServletResponse response) {
        // 构建返回的数据
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", messageCode);
        jsonObject.put("msg", defaultMessage);

        // 设置下返回类型
        response.setContentType(MediaType.APPLICATION_JSON_UTF8.toString());
        // 获取输出流
        try {
            ServletOutputStream out = response.getOutputStream();
            out.write(jsonObject.toJSONString().getBytes());
            out.flush();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.7 自定义HashedCredentialsMatcher认证

package com.wpj.filter;

import com.wpj.exception.BusinessException;
import com.wpj.service.IUserService;
import com.wpj.token.CustomToken;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.springframework.beans.factory.annotation.Autowired;

public class CustomHashedCredentialsMatcher extends HashedCredentialsMatcher {

    @Autowired
    private IUserService userService;

    /**
     * 下面这个方法 返回true 或者 false就决定了 这个是成功呢还是失败
     * @param token
     * @param info
     * @return
     */
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        //  把前面传递过来的token取出来  再把存储到服务器的token取出来做比较
        // 如果一致那么就返回true  否则就返回  false
        CustomToken token1= (CustomToken) token;
        // 取出 Principal的值 (下面这个值 就是从前端传递过来进行比较的)
        String tokenVal= (String) token1.getPrincipal();
        // 从redis  或者  数据库    或者 session取出这个信息来
        boolean flag=false;
        try{
            flag = userService.tokenExistsOrNot(tokenVal);
        }catch (Exception err){
            throw new BusinessException(500001,"查询token存在失败"+err.getMessage());
        }
        //进行比较 判定前端的token和服务端的token是否一致  如果一致  那么返回true  否则返回false
        if(!flag){
            throw new BusinessException(4010000,"授权信息无效请重新登录");
        }
        return true;
    }
}

1.8 自定义Realm

package com.wpj.realm;

import com.wpj.token.CustomToken;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class CustomRealm extends AuthorizingRealm {
    /**
     * 授权的方法
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        return simpleAuthorizationInfo;
    }

    /**
     * 认证的方法
     * 将前端放进去的token 取出来 放到校验的SimpleAuthenticationInfo中去 方便后面进行校验
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //取出前端传递过来的token
        CustomToken customToken= (CustomToken) authenticationToken;
        String token = (String) customToken.getPrincipal();

        //在这里要将前端传递过来的token给封装到 SimpleAuthenticationInfo 对象中去
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(token,token,getName());
        return simpleAuthenticationInfo;
    }
}

1.9 ShiroConfig注入组件

package com.wpj.config;

import com.wpj.filter.CustomAccessControllerFilter;
import com.wpj.filter.CustomHashedCredentialsMatcher;
import com.wpj.realm.CustomRealm;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@SpringBootConfiguration
public class ShiroConfig {
    /**
     * 项目认证(请求资源的时候 身份的认证)的realm
     * @return
     */
    @Bean
    public CustomRealm customRealm(){
        CustomRealm customRealm = new CustomRealm();
        customRealm.setCredentialsMatcher(customHashedCredentialsMatcher());
        return customRealm;
    }

    /**
     * 凭证匹配器的申明
     * @return
     */
    @Bean
    public CustomHashedCredentialsMatcher customHashedCredentialsMatcher(){
        return new CustomHashedCredentialsMatcher();
    }

    /**
     * 安全管理器
     * @return
     */
    @Bean
    public DefaultWebSecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    /**
     * 配置的是目标过滤器的代理
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //配置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //接下来配置些过滤器
        //配置自己的那个过滤器
        Map<String, Filter> map = new LinkedHashMap<>();
        map.put("token",new CustomAccessControllerFilter());
        shiroFilterFactoryBean.setFilters(map);

        //对请求过滤和拦截的设置
        Map<String,String> reqMap=new LinkedHashMap<>();
        //放入不拦截的页面  拦截的页面....
        reqMap.put("/user/login","anon");
        //Swagger的所有请求的资源和请求的地址都不需要拦截
        reqMap.put("/swagger/**","anon");
        reqMap.put("/v2/api-docs","anon");
        reqMap.put("/swagger-ui.html","anon");
        reqMap.put("/swagger-resources/**","anon");
        reqMap.put("/webjars/**","anon");
        reqMap.put("/favicon.ico","anon");
        reqMap.put("/captcha.jpg","anon");
        reqMap.put("/csrf","anon");
        //设置我们自己的校验
        reqMap.put("/**","token,authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(reqMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 开启aop的注解的支持
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        attributeSourceAdvisor.setSecurityManager(securityManager);
        return attributeSourceAdvisor;
    }
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }
}

2. 实例/业务

2.1 定义User类

springboot篇】十六. springboot整合shiro和swagger2实现前后分离_第1张图片

package com.wpj.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
	// 在User类名上alt+/ 自己生成
    private static final long serialVersionUID = 8434196542261610760L;
    
    private Integer id;
    private String name;
    private String pwd;
	private String token;
    private Date expireDate;  //token的过期时间
}

2.2 定义vo(暂时用不着)

package com.wpj.vo;

import com.wpj.pojo.User;

/**
 * 横向扩展
 */
public class CustomUser extends User {
}
package com.wpj.vo;

/**
 * 纵向扩展
 */
public class UserVo {

    private CustomUser customUser;

}

2.3 定义mapper及其xml文件

package com.wpj.mapper;

import com.wpj.pojo.User;

import java.util.List;

/**
 * 用户的DAO接口
 */
public interface IUserMapper {
    /**
     * 通过名字找到用户
     * @param userName
     * @return
     */
    User findUserByName(String userName);

    /**
     * 更新token到数据库
     * @param user
     */
    void updateToken(User user);

    /**
     * 查询所有的用户
     * @return
     */
    List<User> findUserList();
    /**
     * 查看当前的token是否在数据库中存在
     * @param token
     * @return
     */
    User findUserByToken(String token);
}



<mapper namespace="com.wpj.mapper.IUserMapper">

    
    <select id="findUserByName" parameterType="string" resultType="user">
        select * from user where name=#{value}
    select>

    
    <update id="updateToken" parameterType="user">
        update user set token=#{token} where id=#{id}
    update>

    
    <select id="findUserList" resultType="user">
        select * from user
    select>

    
    <select id="findUserByToken" parameterType="String" resultType="user">
        select * from user where token=#{value}
    select>

mapper>

2.4 application配置

mybatis.type-aliases-package=com.wpj.pojo
mybatis.mapper-locations=classpath:mapper/*.xml

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql:///nz1904-shiro-swagger
spring.datasource.username=root
spring.datasource.password=123456

2.5 定义IUserService及其实现类

package com.wpj.service;

import com.wpj.pojo.User;

import java.util.List;

public interface IUserService {
    /**
     * 登陆
     * @param user
     * @return
     */
    User login(User user);

    /**
     * 通过名字找到用户
     * @param userName
     * @return
     */
    User findUserByName(String userName);

    /**
     * 更新token到数据库
     * @param user
     */
    void updateToken(User user);

    /**
     * 查询所有的用户
     * @return
     */
    List<User> findUserList()throws Exception;

    /**
     * 判定这个token是否存在
     * @param token
     * @return
     */
    boolean tokenExistsOrNot(String token);
}
package com.wpj.service.impl;

import com.wpj.exception.BusinessException;
import com.wpj.mapper.IUserMapper;
import com.wpj.pojo.User;
import com.wpj.result.DataResult;
import com.wpj.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class UserServiceImpl implements IUserService {

    @Autowired
    private IUserMapper iUserMapper;

    @Override
    public User login(User user){
        //这个类里面应该干什么?
        /**第一步:获取到前端传递过来的用户名
         *第二步:通过用户名 获取用户对象
         * 第三步:校验
         * 第四步:生成token保存到数据库
         * 第五步:将token封装到返回数据里面给前端
         */
        //获取用户名
        String userName = user.getUserName();
        //通过用户名 找用户名找对象
        User userResult = findUserByName(userName);
        //第三步:校验
        if(null==userResult){  //说明用户名不对
            throw new BusinessException(40001,"用户名不对");
        }
        //说明:用户名是对的
        //比较密码
        if(!(userResult.getPassword().equals(user.getPassword()))){
            throw new BusinessException(40002,"密码不对");
        }
        //执行到这里说明用户身份合法的
        //先将数据保存到一个类里面
        //首先要生成token这个值
        String token= UUID.randomUUID().toString();
        Date date=new Date();
        //设置这个值给user对象
        userResult.setToken(token);
        userResult.setExpireDate(date);
        //下面就是更新这个数据库的数据
        updateToken(userResult);
        //将这个信息返回给前端
        //一般情况下 密码是不需要返回的
        userResult.setPassword("");
        //设置返回数据的对象
        //DataResult userDataResult = new DataResult<>(0,"认证成功",userResult);
        return userResult;
    }

    @Override
    public User findUserByName(String userName) {
        return iUserMapper.findUserByName(userName);
    }

    @Override
    public void updateToken(User user) {
        iUserMapper.updateToken(user);
    }

    @Override
    public List<User> findUserList() throws Exception{
        List<User> userList = iUserMapper.findUserList();
        //接下来对数据进行封装
        DataResult<List<User>> dataResult = new DataResult<>(0, "请求完美", userList);
        return userList;
    }

    @Override
    public boolean tokenExistsOrNot(String token) {
        //通过token查询用户信息
        User userResult = iUserMapper.findUserByToken(token);
        //接下来就要判断了
        if(null!=userResult){
            return true;
        }
        return false;
    }

}

2.5 定义Controller

package com.wpj.controller;

import com.wpj.exception.BusinessException;
import com.wpj.pojo.User;
import com.wpj.result.BaseResponseCode;
import com.wpj.result.DataResult;
import com.wpj.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@Api(tags = {"用户接口"})
public class UserController {

    @Autowired
    private IUserService userService;

    private Logger logger= LoggerFactory.getLogger(UserController.class);

    /**
     * 登陆的接口
     * @param user
     * @return
     */
    @RequestMapping(value = "/user/login",method = RequestMethod.POST)
    @ApiOperation(value = "用户登陆的接口")
    public DataResult<User> login(@RequestBody User user){
        //这个里面应该干什么?
        /**
         * 说白了 调用业务逻辑层的方法
         *  异常的捕获
         *  返回数据
         */
        DataResult<User> dataResult=null;
        try {
            User user1 = userService.login(user);
            dataResult=DataResult.success(user1);
        } catch (Exception e) {
            if(e instanceof BusinessException){  //说明是业务异常
                BusinessException err= (BusinessException) e;
                //应该干什么?
                dataResult=new DataResult<>(err.getMessageCode(),err.getDefaultMessage());
            }else{
                //dataResult=new DataResult<>(500001,"系统异常造成登陆失败");
                dataResult=DataResult.getResult(BaseResponseCode.SYSTEM_ERROR.getCode(),BaseResponseCode.SYSTEM_ERROR.getMsg());
            }
            return dataResult;
        }
        return dataResult;
    }

    /**
     * 查找所有的用户数据
     * @return
     */
    @RequestMapping(value = "/user/list",method = RequestMethod.GET)
    @ApiOperation(value = "获取所有的用户信息")
    @ApiImplicitParam(paramType = "header",name = "token",value = "用户token",required = true,dataType = "String")
    public DataResult<List<User>> findUserList(){
        //定义返回数据
        DataResult<List<User>> userLists;
        try{
            //返回用户数据
            List<User> users = userService.findUserList();
            userLists=DataResult.success(users);
            logger.info("获取数据成功....");
        }catch (Exception err){
            //说明获取信息失败了
            logger.error("获取用户信息失败:"+err.fillInStackTrace());
            userLists=DataResult.getResult(BaseResponseCode.SYSTEM_ERROR.getCode(),BaseResponseCode.SYSTEM_ERROR.getMsg());
        }
        return userLists;
    }
}

2.6 定义全局配置类

/**
 * 全局的配置文件
 */
@SpringBootConfiguration
@ComponentScan(basePackages = {"com.wpj"})
@MapperScan(basePackages = {"com.wpj.mapper"})
public class AppConfig {

}

2.7 启动主启动类访问localhost:8080/swagger-ui.html

你可能感兴趣的:(springboot)