发表于: 2018-02-01 04:13:34
1 716
编辑日报内容...
2018年2月1日星期五
今天完成的事情:
1 spring配置七牛云以及其他properties文件问题
把可能需要改动的配置信息放在properties文件中,用spring注入,这样可以保证后续如果更改配置,不用重启应用?
网上很多文章都是这么写的。但是我测试的时候好像不是这样的。
我试了两种方法:
在xml文件中用构造器注入,value值从properties文件中读取,然后在程序运行过程中,更改properties文件中的值,发现没有任何作用。
我想是这样的,这个java bean在spring容器初始化时,就被创建了,后面无论怎么改properties文件中的内容,也不会再重新创建这个bean。
使用注解@component注解,然后在 类中,读取properties文件中的内容,读取properties内容的方法在创建对象时,如下图:
这种方法,也不行,原因感觉一样,因为创建对象时读取properties文件的内容,
调用方法时,java bean已经被创建,测试更改文件内容也没有效果。
有效果的
但是这样,好像有点浪费啊。不知道师兄怎么做的?
还请指导下。
还有一种方法,用到了apache.commons.configuration这个包,配置了一个propertiesconfig
我测试的时候,好像没什么作用,我看介绍,是说隔一定时间会扫描properties文件,有改动,才反应
那这个隔一段时间,就不是随时触发的了?
还请师兄指教这个动态加载的问题。
2 防止短信和邮件恶意注册以及其他类似的思考
防止短信及邮件恶意注册:
设置最短发送间隔,要在后端设置,需要添加上次发送的时间的字段。
设置指定时间内最大发送次数,例如1天内最多发送10次,可以设定多个阶段。
同一手机号、同一ip限制发送次数。
限制爬虫类的访问。
注册时使用验证码。
3 限制流量、限制方法调用次数的通用解决方法:
按时间限制:
可以用拦截器,添加一个上次调用方法的时间,一个固定时间内调用的次数,如果不符合指定规则,就拦截请求,返回错误。
更复杂的算法:
Token Bucket 算法
https://zhuanlan.zhihu.com/p/20872901?utm_source=tool.lu
4 debug调试的精髓
就是打断点,看内存值
遇到了一个问题,Jackson无法把java bean正确的转为json字符,总是少了数据。
开始debug,第一个断点打在哪?
打在return这,Msg是自定义的返回数据的格式,需要用Jackson把这个Msg格式的数据转为json字符。
然后看stack中的值,单击这个doInvoke方法:看到各种returnValueHandler,这个时候可以上网查下springmvc的大致流程:
而使用@ResponseBody注解后,用RequestResponseBodyMethodProcessor作为HandlerMethodReturnValueHandler,来处理Response数据。
如果有springmvc的知识,这里就可以直接去这个RequestResponseBodyMethodProcessor里边打断点了。可是如果我不知道@ResponseBody是哪个来处理,怎么办呢?
方法就在这几个中:
还要时刻关注,堆栈中变量的变化:
一番调试(很让人眼花缭乱的跳转):
最后,确实,是用了这个RequestResponseBodyMethodProcessor,然后就用了这个handler方法,所以这里打第二个断点:
使用这个强制进入
看到 handleReturnValue,源码:
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
mavContainer.setRequestHandled(true);
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
// Try even with null return value. ResponseBodyAdvice could get involved.
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}
首先mavContainer.setRequestHandled(true),设置成功,表明整个http请求已经处理,后续就不会执行veiw渲染了(跳过render view)。
真正转换数据是最后,把数据放到了outputmessage中。
可以看到,真正转换数据其实是又调用了AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法。
debug进入,这个方法有重载的,看第二个,先是拿到 controller return 对象的类型,然后得到 想要转换的数据类型:
中间省略一些,下面又创建了一个selectedMediaType
再下面就是真正开始处理数据了:
注意那个this. messageConverters 的,debug一下:
这里可以看到Jackson的处理方法就是这MappingJackson2HttpMessageConverter
进入for循环,直到messageConverter为
进入下一步,下面这个就是实际上处理数据:
这里又调用了write方法:
debug进入writeInternal,这里进入到了 AbstractJackson2HttpMessageConverter的writeInternal方法中:
还是这个AbstractJackson2HttpMessageConverter的writeInternal方法,往下翻:
调用 objectWriter.writeValue方法,进入这个方法:
在gen.flush();之后,就看到gen的outputBuffer中有了正真的json字符串:
到这里算是处理完成了,一步步return到writeWithMessageConverters方法中
会有debug信息:
[DEBUG][org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor]-Written [com.bpzj.web.domain.Msg@17401c03] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@53d242a1]
再此return,返回到
处理完成后,数据到底放在哪了呢?就在outputMessage中
然后点击view
乱码是因为,编码还没有转换。下面是postman中请求到的数据:
总结:如果只打一个断点,就想查看Jackson转化后的json字符打在
com.fasterxml.jackson.databind.ser.BeanSerializer.java:155
说下Jackson转换失败的原因吧,setter和getter方法要用public标识符
明天计划的事情:
添加图片验证码,数据迁移。
完成任务7。
遇到的问题:
Jackson不能正确转换java bean到json字符串。
字符串转为map
使用Jackson进行转换
字符串为空或null时处理(入参校验)
传入字符串为string
if(null==string||string.length==0){
}
收获:
debug的用法。
jsr303校验。
评论