一觅赊、spring web mvc默認(rèn)配置沒(méi)有作用
?????? 以前都是使用xml配置方式吮螺,現(xiàn)在切到spring boot還需要一段適應(yīng),好在之前對(duì)實(shí)現(xiàn)本身有所了解坯约。
?????? 問(wèn)題現(xiàn)象:我有部分靜態(tài)資源(html/css/js)放在webapp下莫鸭,運(yùn)行后訪問(wèn) 后臺(tái)報(bào)錯(cuò)“dispatchservlet 沒(méi)有對(duì)應(yīng)的handler”
? ? ? ? 最終原因: 有個(gè)類配置了 @EnableWebMvc?? 注解被因。
? ? ? 解釋:spring boot中 使用 WebMvcAutoConfiguration 已經(jīng)自動(dòng)化做了默認(rèn)配置衫仑。如果自己要全部重寫文狱,使用 @EnableWebMvc注解缘挽;如果僅是擴(kuò)展或重寫原有部分配置,extends WebMvcConfigurerAdapter 即可苏研。? 關(guān)于WebMvcAutoConfiguration 的默認(rèn)配置摹蘑,可以參考:http://blog.csdn.net/isea533/article/details/50412212?
對(duì)于MVC里的viewResolver轧飞、interceptors过咬、靜態(tài)資源、formatter和converter兼犯、HttpMessageConverts集漾、Servlet砸脊、Filter凌埂、Listener等,Spring Boot使用了一個(gè)叫WebMvcAutoConfiguration和WebMvcProperties的文件來(lái)進(jìn)行自動(dòng)配置
二埃疫、集成UAA 栓霜,跨域問(wèn)題
問(wèn)題現(xiàn)象:(1)使用jsonp横蜒,405錯(cuò)销凑;(2)來(lái)自 CORS 預(yù)檢通道的 CORS 頭 'Access-Control-Allow-Headers' 的令牌 'authorization' 無(wú)效
最終原因:安全問(wèn)題斗幼,禁止跨域訪問(wèn)抚垄;
解釋:跨域 服務(wù)端可以支持呆馁,spring boot 可以使用 @CrossOrigin(origins="http://localhost:9000")? 【其支持origins,methods,allowedHeaders,exposedHeaders,allowCredentials,maxAge】這樣的注解,但 UAA的http服務(wù)是框架提供的次询,我們就自己寫了一個(gè)crossfilter瓷叫,如:
if(request.getRequestURI().contains("oauth") || request.getRequestURI().contains("login") ||request.getRequestURI().contains("logout")|| request.getRequestURI().contains("checkAccessTokenIsExpire") || request.getRequestURI().contains("account")) {
// CORS "pre-flight" request
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Headers","X-Requested-With");
response.setHeader("Access-Control-Allow-Headers","Authorization");
response.setHeader("Access-Control-Allow-Methods","POST, GET, OPTIONS");
response.setHeader("Access-Control-Max-Age","1800");
response.addHeader("Access-Control-Allow-Credentials","true");
}
filterChain.doFilter(request, response);
問(wèn)題(2)只需要加上 上面黑體部分即可 摹菠!
三次氨、出現(xiàn) java.lang.NoSuchMethodError: com.alibaba.druid.sql.ast.expr.SQLAggregateExpr.getOption()Lcom/alibaba/druid/sql/ast/expr/SQLAggregateExpr$Option;? 錯(cuò)誤
問(wèn)題現(xiàn)象:count的sql執(zhí)行時(shí)出現(xiàn) 錯(cuò)誤:
java.lang.NoSuchMethodError:com.alibaba.druid.sql.ast.expr.SQLAggregateExpr.getOption()Lcom/alibaba/druid/sql/ast/expr/SQLAggregateExpr$Option;
我使用的是 alibaba 的 druid連接池 和 dangdang 的sharding-jdbc煮寡。
最終原因: druid? 的 1.0.23版本有bug, 降到 1.0.12 就好了
解釋:
四薇组、切換git服務(wù)器
問(wèn)題現(xiàn)象:github訪問(wèn)太慢坐儿,遷移到oschina貌矿,而且其免費(fèi)支持私有項(xiàng)目,不錯(cuò)黑低。
具體操作參見(jiàn)此博文:
http://yijiebuyi.com/blog/f18d38eb7cfee860c117d629fdb16faf.html
五尽楔、gradle refresh出錯(cuò)
因?yàn)?我們使用了dubbox,我是知道的娇掏,它并沒(méi)有發(fā)布到maven中心庫(kù)勋眯,所以每次需要發(fā)布到本地maven庫(kù)客蹋,有些團(tuán)隊(duì)同學(xué)不知道,gradle import工程就會(huì)報(bào)錯(cuò) 番电,如下:(DefaultModuleVersionSelector)
坑爹的是 這個(gè)提示太含混了漱办,看 錯(cuò)誤日志 也是 一個(gè) 序列化的錯(cuò)誤婉烟,摸不著頭腦似袁。就是倉(cāng)庫(kù)中找不到依賴包
6. 打包后的war啟動(dòng)不起來(lái)
題外話:因?yàn)?spring boot以jar的形式啟動(dòng)web應(yīng)用,我看libs下面生成的是war扬霜,以為要用其他方式才能打包成jar而涉,找了半天才發(fā)現(xiàn)war只是個(gè)馬甲Sて住G麦向!
打包很簡(jiǎn)單,我使用的是gradle话告,所以 在 對(duì)應(yīng) module下 運(yùn)行 gradle build即可沙郭,問(wèn)題現(xiàn)象:但生成之后 我運(yùn)行? java -jar ****.war? ? mybatis的domain報(bào)classnotfoundexception
最終原因:mybatis的class掃描機(jī)制有bug
解釋:http://www.scienjus.com/mybatis-vfs-bug/??? 這邊文章寫的很清晰,自己看吧吓著。
延伸閱讀: 我這邊使用的 是? mybatis? 3.4.1送挑,mybatis的class掃描接口有變動(dòng)惕耕,對(duì)應(yīng)的掃描實(shí)現(xiàn)類 代碼增加如下方法重載:
?@Override
publicList list(String path)throwsIOException {
ClassLoader cl =this.getClass().getClassLoader();
ResourcePatternResolver resolver =newPathMatchingResourcePatternResolver(cl);
Resource[] resources = resolver.getResources(path +"/**/*.class");
List resources1 = Arrays.asList(resources);
List resourcePaths =newArrayList();
for(Resource resource: resources1) {
resourcePaths.add(preserveSubpackageName(resource.getURI(), path));
}
returnresourcePaths;
}
7.我們使用了UAA司澎,另一個(gè)系統(tǒng)的web頁(yè)面調(diào)用登錄時(shí),報(bào)錯(cuò)浪南,如下:
因?yàn)榭缬蛑С致缭洌覀冊(cè)?UAA server增加了 CrossFilter絮记,代碼如下:
response.setHeader("Access-Control-Allow-Origin","*");
response.setHeader("Access-Control-Allow-Headers","X-Requested-With");
response.setHeader("Access-Control-Allow-Headers","Authorization");
response.setHeader("Access-Control-Allow-Methods","POST, GET, OPTIONS");
response.setHeader("Access-Control-Max-Age","1800");
//? ? ? ? ? ? response.setHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Allow-Credentials","true");
引發(fā)問(wèn)題的原因 就是注釋掉的那一行怨愤,注釋掉即可 正常蛹批。
具體原因: 是自己大意所致腐芍,大家都知道它背后其實(shí)是一個(gè)map實(shí)現(xiàn)肮蛹,而 多次調(diào)用 “Access-Control-Allow-Headers” 導(dǎo)致了value被覆蓋, 就導(dǎo)致了上面的錯(cuò)誤。其實(shí)對(duì)于有多值的key 調(diào)用 addHeader 即可。
其實(shí)說(shuō)白了,就是 錯(cuò)誤的本質(zhì)原因 就是跨域時(shí) 有header 跨域服務(wù)器不允許的外冀!
8. UAA 不支持? additional_information
問(wèn)題現(xiàn)象:我們給 oauth_client_details數(shù)據(jù)表的 additional_information字段增加了擴(kuò)展屬性值锥惋,但在 encode token值后發(fā)現(xiàn)并沒(méi)有 additional_information的值膀跌。
最終原因:spring-security-oauth2 2.0.11-RELEASE的bug
解釋:DefaultOAuth2RequestFactory 生成 的是? TokenRequest 實(shí)例,而TokenRequest的實(shí)現(xiàn)并沒(méi)有支持 additional_information劫流, 看代碼:
newOAuth2Request(modifiable, client.getClientId(), client.getAuthorities(),true,this.getScope(),client.getResourceIds(),null,null,null)
最后一個(gè)參數(shù)傳null丛忆, 這酸爽(不支持 additional_information)熄诡!
9. CSRF Token錯(cuò)誤
問(wèn)題現(xiàn)象:表單 post 請(qǐng)求,報(bào)錯(cuò)? “”
最終原因:正如錯(cuò)誤提示我抠,沒(méi)有 傳遞足夠的信息到服務(wù)端
解釋:spring security 新版本增加了 csrf特性菜拓, 正確的服務(wù)端交互 需要 增加? header “CSRF-TOKEN”? 或 增加 _csrf 參數(shù)
10. application.properties設(shè)置了 logging.path 不起作用
問(wèn)題現(xiàn)象:沒(méi)有在指定路徑輸出日志纳鼎,而是輸出到了臨時(shí)目錄
最終原因:依賴了spring cloud 包導(dǎo)致的裳凸,去除依賴ok
解釋:spring cloud 包 中包含 BootstrapApplicationListener姨谷。具體要了解spring boot的啟動(dòng)原理,spring boot應(yīng)用啟動(dòng)時(shí) 會(huì) 逐一運(yùn)行ApplicationListener,spring boot 包裝的logging處理 先在執(zhí)行 BootstrapApplicationListener時(shí)初始化了一遍logback,第二次走 ApplicationListener時(shí)不會(huì)重新初始化logback所致践叠。
問(wèn)題排查:(笨方法)
我們知道FileAppender言缤,知道其會(huì)設(shè)置 fileName,其是通過(guò)FileAppender的setFile實(shí)現(xiàn)的禁灼,在這里設(shè)置斷點(diǎn)管挟,發(fā)現(xiàn)第一次會(huì)設(shè)置,第二次不會(huì)弄捕,沿著調(diào)用堆棧 會(huì)找到LogbackLoggingSystem的initialize方法僻孝,其中有判斷 isAlreadyInitialized()