先扯两句
既然前面已经开了这个先河,那闲着也是闲着,就把遇到的其他后台的问题也一并记录一下吧,说不好以后是不是用的上呢。
PS:你没看错,上面那张图就是鸡贼:
正文
我先把这个问题说一下,看看大家能不能看得明白,我自己都感觉像一个绕口令一样。
首先,是我的拦截器设置了,但是并没有起到作用,调用接口还是直接进入到Controller中,于是搜索了一下网上的解决方案,给出的方案就是在拦截器添加@Component注解,并在Application添加@ComponentScan({"拦截器所在目录"})
import com.alibaba.fastjson.JSON;
import com.bsw.blog.annotation.LoginInterceptorWhitelist;
import com.bsw.blog.controller.UserController;
import com.bsw.blog.result.ResultBody;
import com.bsw.blog.result.ResultStateEnum;
import com.bsw.blog.util.Constants;
import com.bsw.blog.util.LogUtils;
import com.bsw.blog.util.TextUtils;
import com.bsw.blog.util.redis.Redis0Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 登录拦截器
*
* @author 半寿翁
* @date 2020-8-31 20:15
*/
@Component
@Configuration
public class LoginInterceptor implements HandlerInterceptor {
@Autowired
@Resource(name = "redis")
private RedisTemplate stringRedisTemplate;
/**
* 日志打印
*/
private final LogUtils log = new LogUtils(UserController.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 请求的方法是否有注解
if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
// 检测是否有 @OnlyAdmin 注解
LoginInterceptorWhitelist oa = ((HandlerMethod) handler).getMethodAnnotation(LoginInterceptorWhitelist.class);
log.i(request.getRequestURI() + request.getMethod());
if (null == oa) {
...
} else {
return true;
}
}
response.setStatus(401);
response.sendError(401, "登录失效");
ResultBody resultBody = new ResultBody(ResultStateEnum.RESULT_LOGIN_TIMEOUT);
returnJson(response, JSON.toJSONString(resultBody));
return false;
}
}
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
@SpringBootApplication(exclude = {
RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@ComponentScan("com.bsw.blog.interceptor"),
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
满怀希望的运行一下,结果直接报错了,查看一下错误日志中的提示:
Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
于是去查,这个问题怎么解决,得到的方案是:
去掉@SpringBootApplication()的DataSourceAutoConfiguration.class
于是把上面的代码Application的注解改成了
@SpringBootApplication(exclude = {
RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class,
// DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@ComponentScan("com.bsw.blog.interceptor"),
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
调整后重新编译,没一会就得到了新的报错,好兴奋啊,提示信息如下:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
有了新的错误,没关系,我们接着百度,果然得到了新的解决方案:
在@SpringBootApplication()添加上DataSourceAutoConfiguration.class,
我TM,老子为了解决上一个问题,刚去掉,这就让我加回去。
纠结半天,终于想到办法,我还是叫外卖吧。。。通过查找@SpringBootApplication与@ComponentScan的冲突问题,终于看到了胜利的曙光——SpringBoot踩坑记录(@SpringBootApplication与@ComponentScan存在冲突)
(1)只有@SpringBootApplication,日志正常打印@SpringBootApplication默认会扫描同包及子包,所以TestController被扫描,打印日志
(2)存在@SpringBootApplication和一个@ComponentScan注解,不打印日志@ComponentScan注解会先被处理,然后返回,使得@SpringBootApplication中的配置没有生效
(3)存在@SpringBootApplication和多个@ComponentScan注解,日志正常打印
所以在Application中做了如下调整:
@SpringBootApplication(exclude = {
RedisAutoConfiguration.class,
RedisRepositoriesAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class
})
@ComponentScans({
@ComponentScan("com.bsw.blog.interceptor"),
@ComponentScan("com.bsw.blog.mapper"),
})
public class BlogApplication {
public static void main(String[] args) {
SpringApplication.run(BlogApplication.class, args);
}
}
你没看错,就是添加了一条没有用的mapper的ComponentScans,然后项目真的正常运行了,啥也不说了,谁去给SpringBoot提个bug去。。。
鸣谢
- 鸡贼:来自Pixabay的Ryan McGuire
- 没有口罩出去买:来自出门买不到口罩,没口罩不能出门,我太难了