mybatis中传入多个参数时,应该使用@param注解

报错

1
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]

修改

1
2
3
4
/**
* 查询某个主题下最新的通知
*/
Message selectLatestNotice(@Param("userId")String userId, @Param("topic")String topic);

由于打jar包后static文件读取路径问题,无法读取文件

只能用URL来读,用file,字节流都报错

修改

1
2
3
4
5
@Value("${sensitive.filename}")
private void flashRedisKey(String filename) throws IOException {
ClassLoader classLoader = this.getClass().getClassLoader();
URL resource = classLoader.getResource("static/" + filename);
}

rabbitMQ队列需要先声明

rabbitMQ队列如果没提前新建,消费者会报错。

修改

  1. 添加配置信息
  2. 手动添加队列

rabbitMQ简单业务不需要声明交换机,使用默认交换机即可

数据库中有”的数据,直接返回给前端对应的字符串,其中就会出现对应的 “\ 的转义符号

场景

某数据库对象中content字段是字符串类型,考虑到扩展性,里面存储的是键值对如:{“entityType”:”article”,”entityId”:”1”,”userId”:”2”}

此时直接将这条数据查出后返回给前端会带有”\转义符号

1
2
3
"data": {
"content": "{\"entityType\":\"user\",\"entityId\":\"2\",\"userId\":\"111111\"}"
}

解决

在不影响其他业务的要求下,新建应该DTO类,继承原来的类,并新增一个map类型的成员变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MessageDTO extends Message {
private HashMap<String,String> contentMap;

public HashMap<String, String> getContentMap() {
return contentMap;
}

public void setContentMap(HashMap<String, String> contentMap) {
this.contentMap = contentMap;
}

public MessageDTO() {
}

public MessageDTO(Message message) {
super(message.getId(),message.getFromId(),message.getToId(), message.getConversionId(), message.getContent(), message.getStatus(),message.getCreatedTime());
}
}

日志文件配置

问题

springboot配置日志时,由于application.yml配置不够完全,引入logback-spring.xml进行详细配置

但配置不起效果

解决

需要在application.yml中配置

1
2
3
4
5
6
7
8
spring:
profiles:
active: prod

logging:
config: classpath:logback-spring.xml
# level: #默认info,开发时用debug
# com.yxz.wulibibiji: info

前端部署,接口无法访问(nginx代理之巨坑!!!)

问题,巨坑!!!

前端项目部署后,API请求变成请求页面,无法正确发送请求到后端服务器

发生这个问题肯定是需要对api的路径nginx做代理,但是如下设置后还是报404错

1
2
3
4
5
6
location /api/ {
proxy_pass http://wlbbj.yangxiaobai.top;
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

加 / 与不加 /

在配置proxy_pass代理转发时,如果后面的url加/,表示绝对根路径;如果没有/,表示相对路径

例如

加 /

1
2
3
4
server_name shaochenfeng.com
location /api/ {
proxy_pass http://127.0.0.1/;
}

访问 http://wulibbj.top/api/article/new 会转发到 http://127.0.0.1/article/new

不加 /

1
2
3
4
server_name shaochenfeng.com
location /data/ {
proxy_pass http://127.0.0.1;
}

前端部署,子页面报404

问题

明明存在这个子路径却访问时报404

解决

在nginx中配置

1
2
3
location / {
try_files $uri $uri/ /index.html;
}

同样的sql每次查询的结果不同

1
2
3
4
5
6
7
8
9
10
11
12
SELECT
firstComment.*,
nickname AS `name`,
avatar
FROM
`firstComment`
LEFT JOIN `user` ON user.user_id = firstComment.first_comment_user_id
WHERE
(first_comment_article_id = 86)
ORDER BY
first_comment_like_count DESC
LIMIT 10,

当sql为上述时候,测试数据库有多个first_comment_like_count为0的数据,每次查询,顺序和所包含的数据都会有变换。

解决

再加一个id排序,其他业务接口同理

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
firstComment.*,
nickname AS `name`,
avatar
FROM
`firstComment`
LEFT JOIN `user` ON user.user_id = firstComment.first_comment_user_id
WHERE
(first_comment_article_id = 86)
ORDER BY
first_comment_like_count DESC,
first_comment_id ASC
LIMIT 10,

定时任务没执行-报空指针异常

部署发现有好长几天的uv没有统计进mysql数据库,查到后台报了空指针异常

猜测是复现bug

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2023-02-18 13:11:20.011 logback [scheduling-1] ERROR o.s.s.s.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task
java.lang.NullPointerException: null
at com.yxz.wulibibiji.config.ServiceLogAspect.before(ServiceLogAspect.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:626)
at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:44)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:55)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
at com.yxz.wulibibiji.service.impl.UvcountServiceImpl$$EnhancerBySpringCGLIB$$fae63f46.getAll(<generated>)
at com.yxz.wulibibiji.config.UVScheduledConfiguration.test(UVScheduledConfiguration.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)

怀疑一

发现有人也在使用scheduled时,autowired可能注入空的对象

springboot在使用Scheduled做定时任务出现Autowired注入空指针_scdn

原因:Scheduled的加载时机要早于Autowired;

解决:通过在ApplicationContext中按名称查找service

发现还是没解决

怀疑二

由于我aop记录日志是,记录了每个请求的时间,ip等信息,但是切点是service下的每个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
@Aspect
@Slf4j
public class ServiceLogAspect {
@Pointcut("execution(* com.yxz.wulibibiji.service.*.*(..))")
public void pointcut() {

}

@Before("pointcut()")
public void before(JoinPoint joinPoint) {// 参数:连接点
// 用户[1.2.3.4],在[xxx],访问了[com.nowcoder.community.service.xxx()].
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String ip = request.getRemoteHost();
String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(DateUtil.date());
String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();// 得到该连接点的类名和方法名
log.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target));
}
}

这就造成了大问题,如果是我业务内部调用service的方法,那么ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();就会得到空的对象,在后续使用中报空指针异常。

解决方法

  1. 修改AOP切点的位置,到controller层中
1
@Pointcut("execution(* com.yxz.wulibibiji.controller.*.*(..))")
  1. 对于attributes做非空判断
1
2
3
4
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null) {
return;
}