一、spring web mvc默認(rèn)配置沒有作用
?????? 以前都是使用xml配置方式,現(xiàn)在切到spring boot還需要一段適應(yīng),好在之前對實(shí)現(xiàn)本身有所了解。
?????? 問題現(xiàn)象:我有部分靜態(tài)資源(html/css/js)放在webapp下,運(yùn)行后訪問 后臺報(bào)錯(cuò)“dispatchservlet 沒有對應(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?
對于MVC里的viewResolver、interceptors、靜態(tài)資源、formatter和converter、HttpMessageConverts、Servlet、Filter、Listener等,Spring Boot使用了一個(gè)叫WebMvcAutoConfiguration和WebMvcProperties的文件來進(jìn)行自動(dòng)配置
二、集成UAA ,跨域問題
問題現(xiàn)象:(1)使用jsonp,405錯(cuò);(2)來自 CORS 預(yù)檢通道的 CORS 頭 'Access-Control-Allow-Headers' 的令牌 'authorization' 無效
最終原因:安全問題,禁止跨域訪問;
解釋:跨域 服務(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);
問題(2)只需要加上 上面黑體部分即可 !
三、出現(xiàn) java.lang.NoSuchMethodError: com.alibaba.druid.sql.ast.expr.SQLAggregateExpr.getOption()Lcom/alibaba/druid/sql/ast/expr/SQLAggregateExpr$Option;? 錯(cuò)誤
問題現(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ù)器
問題現(xiàn)象:github訪問太慢,遷移到oschina,而且其免費(fèi)支持私有項(xiàng)目,不錯(cuò)。
具體操作參見此博文:
http://yijiebuyi.com/blog/f18d38eb7cfee860c117d629fdb16faf.html
五、gradle refresh出錯(cuò)
因?yàn)?我們使用了dubbox,我是知道的,它并沒有發(fā)布到maven中心庫,所以每次需要發(fā)布到本地maven庫,有些團(tuán)隊(duì)同學(xué)不知道,gradle import工程就會報(bào)錯(cuò) ,如下:(DefaultModuleVersionSelector)

坑爹的是 這個(gè)提示太含混了,看 錯(cuò)誤日志 也是 一個(gè) 序列化的錯(cuò)誤,摸不著頭腦。就是倉庫中找不到依賴包
6. 打包后的war啟動(dòng)不起來
題外話:因?yàn)?spring boot以jar的形式啟動(dòng)web應(yīng)用,我看libs下面生成的是war,以為要用其他方式才能打包成jar,找了半天才發(fā)現(xiàn)war只是個(gè)馬甲?。?!
打包很簡單,我使用的是gradle,所以 在 對應(yīng) module下 運(yùn)行 gradle build即可,問題現(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),對應(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頁面調(diào)用登錄時(shí),報(bào)錯(cuò),如下:

因?yàn)榭缬蛑С?,我們?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ā)問題的原因 就是注釋掉的那一行,注釋掉即可 正常。
具體原因: 是自己大意所致,大家都知道它背后其實(shí)是一個(gè)map實(shí)現(xiàn),而 多次調(diào)用 “Access-Control-Allow-Headers” 導(dǎo)致了value被覆蓋, 就導(dǎo)致了上面的錯(cuò)誤。其實(shí)對于有多值的key 調(diào)用 addHeader 即可。
其實(shí)說白了,就是 錯(cuò)誤的本質(zhì)原因 就是跨域時(shí) 有header 跨域服務(wù)器不允許的!
8. UAA 不支持? additional_information
問題現(xiàn)象:我們給 oauth_client_details數(shù)據(jù)表的 additional_information字段增加了擴(kuò)展屬性值,但在 encode token值后發(fā)現(xiàn)并沒有 additional_information的值。
最終原因:spring-security-oauth2 2.0.11-RELEASE的bug
解釋:DefaultOAuth2RequestFactory 生成 的是? TokenRequest 實(shí)例,而TokenRequest的實(shí)現(xiàn)并沒有支持 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ò)誤
問題現(xiàn)象:表單 post 請求,報(bào)錯(cuò)? “”
最終原因:正如錯(cuò)誤提示,沒有 傳遞足夠的信息到服務(wù)端
解釋:spring security 新版本增加了 csrf特性, 正確的服務(wù)端交互 需要 增加? header “CSRF-TOKEN”? 或 增加 _csrf 參數(shù)
10. application.properties設(shè)置了 logging.path 不起作用
問題現(xiàn)象:沒有在指定路徑輸出日志,而是輸出到了臨時(shí)目錄
最終原因:依賴了spring cloud 包導(dǎo)致的,去除依賴ok
解釋:spring cloud 包 中包含 BootstrapApplicationListener。具體要了解spring boot的啟動(dòng)原理,spring boot應(yīng)用啟動(dòng)時(shí) 會 逐一運(yùn)行ApplicationListener,spring boot 包裝的logging處理 先在執(zhí)行 BootstrapApplicationListener時(shí)初始化了一遍logback,第二次走 ApplicationListener時(shí)不會重新初始化logback所致。
問題排查:(笨方法)
我們知道FileAppender,知道其會設(shè)置 fileName,其是通過FileAppender的setFile實(shí)現(xiàn)的,在這里設(shè)置斷點(diǎn),發(fā)現(xiàn)第一次會設(shè)置,第二次不會,沿著調(diào)用堆棧 會找到LogbackLoggingSystem的initialize方法,其中有判斷 isAlreadyInitialized()