一、IDEA gradle 創建springboot項目後 cannot resolve symbol ‘SpringBootApplication’
用IDEA創建springboot項目,構建方式爲gradle,創建完成後不能識別SpringBootApplication 註解
很多解決方法,比如 gradle clean,或者 file–invalidata caches/restart 都沒有用
原來是因爲gradle構建dependencies時,有的jar是隻在運行時有效的
它是developmentOnly的,在編譯時找不到,所以報錯。
這時必須手動將這些jar包放到項目的dependencies中用於編譯
具體步驟爲
- 在項目根目錄下創建文件夾,比如libs
- 然後在build.gradle文件中新建一個task,用來拷貝jar包
task copyJars(type:Copy){ from configurations.developmentOnly into 'libs' }
- 然後在命令窗口中執行這個命令
gradle copyJars
因爲我的已經執行過了,所以直接成功了,正常執行後會有一個過程,中間出現錯誤會報出來。沒有錯誤看到BUILD SUCCESSFUL
就表示完成了。這時拷貝的所有jar包就會出現在libs文件夾裏
- 然後 file–project structure–modules–dependencies,點擊下面的+號添加目錄,選擇你剛纔創建的libs文件夾,把所有jar包都加進去
這裏一定選擇compile,當然默認就是,然後apply–ok,問題就解決了
二、用主類的main方法啓動後,訪問tomcat一直報404
解決方法,不要用main方法啓動項目,要用gradle bootRun
命令啓動,至於爲什麼還不是很清楚
三、springboot 自帶的網絡工具 RestTemplate大坑
(這個東西真是坑死我了!!)
- 首先,在類中想要用
@Autowired
注入它的對象時會報錯,
這時必須手動創建RestTemplate類的beanField client in com.eqchu.project.httpRequest.Http required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found. The injection point has the following annotations: - @org.springframework.beans.factory.annotation.Autowired(required=true) Action: Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
注意,創建的MainConfig類必須在主類能掃描到的地方,就是在主類的同級或者下級目錄,否則還會報錯@Configuration public class MainConfig { @Bean public RestTemplate restTemplate() { RestTemplate et = new RestTemplate(); return et; } }
- RestTemplate發送網絡請求的默認編碼方式是ISO_8859_1,如果貿然使用,會造成未知的亂碼錯誤,所以使用之前最好改編碼集。改編碼集的方式爲在上面的代碼中加入一行
@Configuration public class MainConfig { @Bean public RestTemplate restTemplate() { RestTemplate et = new RestTemplate(); et.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8)); return et; } }
- 然後,就是最坑的地方,RestTemplate自帶的編碼方式和java的URLEncode方法是不一樣的,所以使用其任何的請求方法時,傳入的url最好不要是String,而應該是URI對象,否則會引起參數錯誤。
原因在這裏,就不抄別人的了。@Test public void testUrlEncode() { String url = "http://localhost:39531/access?accessKey=ASHJRK3LJFD%2BR32SADFLK%2BFASDJ%3D&name=yihuihui"; RestTemplate restTemplate = new RestTemplate(); //錯誤 String ans = restTemplate.getForObject(url, String.class); //正確 String ans = restTemplate.getForObject(URI.create(url), String.class); System.out.println(ans); }
因爲這個原因,其傳遞的參數字符串中最好也不要有+號,否則會引起數據錯誤。
四、controller 返回字符串時會報類型錯誤 JSONObject can not be cast to String
controller返回List或者Map時沒有問題,但是返回String就會報錯,解決方法時新建一個config萊配置返回體
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.*;
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//針對字段的處理
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.WriteNullListAsEmpty,// List字段如果爲null,輸出爲[],而非null
SerializerFeature.WriteMapNullValue,//加上後,字段爲null的也會輸出
SerializerFeature.WriteNullStringAsEmpty,//字符類型字段如果爲null,輸出爲”“,而非null
SerializerFeature.WriteNullBooleanAsFalse,//Boolean字段如果爲null,輸出爲false,而非null
SerializerFeature.PrettyFormat //結果是否格式化,默認爲false
);
//日期格式化
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
converter.setFastJsonConfig(fastJsonConfig);
converters.add(0,converter);//返回是string的話,默認把這個放在最前,否則ResponseAdvisor 處理字符串返回時會報類型不一致
}
}
五、Failed to instantiate xxx
自建bean後,啓動項目時有時會報bean找不到,或者初始化不成功,導致項目啓動失敗。原因很簡單,是因爲自建的bean沒有默認構造方法;springboot管理所有bean都需要默認的構造方法,也就是無參構造方法,手動加上後問題就會解決。