springmvc-沒有web.xml和springmvc.xml你還可以執行起來springmvc嗎
前面也寫了幾篇有關springboot的簡單使用的文章,也寫了幾篇有關springcloud的文章,不過springcloud是基於springboot的。所以就來糾結一下springboot的吧。
springboot之所以可以不用使用任何的xml配置檔案就可以實現web的配置和釋出,在前期的spring中已經加入了很多的元素,用於實現這些功能。
本篇主要介紹兩個內容:1)不使用web.xml釋出一個web專案;2)不使用springmvc.xml配置檔案,實現messageconverter的更換。
1.不使用web.xml配置檔案釋出一個web專案。
1.1先引入jar包
因為近期在研究spring的原始碼,所以乾脆直接把專案建到spring的模組下面,作為spring的子專案,方便debug和註釋。這裡也就使用gradle構建,為了執行不出現問題,沒有使用原始碼引入的還是jar包。這裡跟maven相差不大,也就是把maven中座標版本資訊groupId,artifactId,version摳出來放到gradle中的group,name,version中。這裡可以先拷貝模板,然後配置一下即可,不再多言。
group 'org.springframework' version '5.0.3.BUILD-SNAPSHOT' apply plugin: 'java' apply plugin: 'war' sourceCompatibility = 1.8 /*repositories { mavenCentral() }*/ //將倉庫更換為阿里雲倉庫 allprojects { repositories { maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} } } dependencies { compile group: 'org.springframework',name: 'spring-core',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'org.springframework',name: 'spring-beans',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'org.springframework',name: 'spring-expression',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'org.springframework',name: 'spring-context',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'org.springframework',name: 'spring-web',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'org.springframework',name: 'spring-webmvc',version: '5.0.3.BUILD-SNAPSHOT' compile group: 'commons-logging', name: 'commons-logging', version: '1.2' compile group: 'commons-collections', name: 'commons-collections', version: '3.2.1' compile group: 'commons-io', name: 'commons-io', version: '2.4' compile group: 'commons-fileupload', name: 'commons-fileupload', version: '1.3.1' compile group: 'commons-codec', name: 'commons-codec', version: '1.10' compile group: 'jstl', name: 'jstl', version: '1.2' compile group: 'javax', name: 'javaee-api', version: '7.0' compile group: 'log4j', name: 'log4j', version: '1.2.17' compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.24' compile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.24' /*springmvc預設使用的jackson*/ compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.5' compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.5' compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.5' /*將jackson跟換為fastjson,需要修改messageconverter*/ /*compile group: 'com.alibaba', name: 'fastjson', version: '1.2.33'*/ testCompile group: 'junit', name: 'junit', version: '4.12' }
1.2工程目錄
MvcUser-例項物件 HelloController-controller類 [email protected] 容器類 WebMvcInitializer-web配置類
1.3看程式碼 MvcUser
public class MvcUser implements Serializable{
private String id;
private String name;
private Integer age;
private String email;
public MvcUser(String id, String name, Integer age, String email) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
HelloController
@RestController
public class HelloController {
@GetMapping("/get/{id}")
public MvcUser getMvcUser(@PathVariable("id") String id){
System.out.println("查詢id:"+id);
MvcUser mu = new MvcUser("1","zhangsan",19,"[email protected]");
return mu;
}
}
這裡的@RestController是組合註解@[email protected] @GetMapping是簡化版的Get請求,類似於@RequestMapping+Get方法 其他配置都是一樣的。 由於前面相當於已經配置了@ResponseBody,所以在方法上面就不在配置,直接返回物件型別。
@Configuration
@ComponentScan("com.mvc")
@EnableWebMvc
public class MvcConfig{
/**
* 配置檢視解析器
* @return
*/
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}
這裡配置檢視解析器。@[email protected]就相當於一個IOC容器。新增@Bean的方法就類似於一個bean。所以在這裡新增跟在xml配置檔案中新增一個<bean>
標籤是一樣的。
所以在這裡新增viewResolver()方法,實際上就是相當於配置了檢視解析器。
1.5web配置
/**
* 取代web.xml配置檔案
*/
public class WebMvcInitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(MvcConfig.class);
ctx.setServletContext(servletContext);
Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
dispatcher.addMapping("/");
dispatcher.setLoadOnStartup(1);
}
}
實現WebApplicationInitializer。實現中間的onStartup()方法,並在方法中配置servlet,filter,listener就等價於配置了web.xml配置檔案,並在配置檔案中實現一樣。
比如這裡配置了DispatcherServlet,並設定Mapping為/,啟動時機。
做好這些配置之後是不是就可以啟動了呢?試一下
run on server
不需要web.xml配置檔案,不需要springmvc.xml配置檔案的web專案成功的釋出且正常對外提供了服務。
2.messageconverter更換
springmvc能夠直接返回json是因為springmvc底層依賴了jackson。那麼我現在遇到了問題,我想使用alibaba的fastjson該怎麼辦呢,我的資料轉換出現了亂碼該怎麼辦呢? 使用xml配置檔案的時候,我們可以通過下面的形式進行配置。
<mvc:annotation-driven>
<mvc:message-converters>
<ref bean="stringHttpMessageConverter"></ref>
<ref bean="mappingJackson2HttpMessageConverter"></ref>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
<!-- 後臺json中文正常,傳遞到前臺後出現亂碼,加一下配置解決jsp頁面亂碼問題 -->
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
<bean id="mappingJackson2HttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
這樣就可以解決問題了。那麼沒有配置檔案我們該怎麼辦呢? 可以這樣弄 2.1先引入fastjson
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.33'
2.2使用WebMvcConfigurerAdapter
@Configuration
@ComponentScan("com.mvc")
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
/**
* 配置檢視解析器
* @return
*/
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
@Bean
public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
//1.需要定義一個convert轉換訊息的物件;
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
//2.新增fastJson的配置資訊,比如:是否要格式化返回的json資料;
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//3處理中文亂碼問題
List<MediaType> fastMediaTypes = new ArrayList<>();
fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
//4.在convert中新增配置資訊.
fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
return fastJsonHttpMessageConverter;
}
/**
* springmvc原生的message使用的是jackson,現在想更換為fastjson的,需要經過兩步處理
* 1.將fastjson messageconverter加入到ioc容器中
* 2.將fastjson messageconverter加入到converters組中
* 繼承WebMvcConfigurerAdapter類並重寫extendMessageConverters()方法
*
* 注意:現在的WebMvcConfigurerAdapter 類已經過時,但是還可以使用。
* 如果擔心以後不再支援,可以繼承新的類WebMvcConfigurationSupport,但是通過配置,發現沒法執行,所以還是沿用之前的吧
*
* 講過上面的兩步操作,就完成了fastjson的整合
* @param converters
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(fastJsonHttpMessageConverter());
}
}
繼承WebMvcConfigurerAdapter
類,然後重寫extendMessageConverters()
。然後將fastjson的實現加入到converters
組中。然後再啟動服務,就好了(前提是先把jackson註釋掉)。
通過上面的步驟我們就完成了MessageConverter
的更換。
但遺憾的是WebMvcConfigurerAdapter
類已經過期了。
替代WebMvcConfigurerAdapter
類的是WebMvcConfigurationSupport
和WebMvcConfigurer
。但是實現了WebMvcConfigurationSupport
介面,配置的MessageConverter
卻不起作用。實現WebMvcConfigurer
可以使用。
好了,就寫到這裡。
我去瞅瞅為啥實現WebMvcConfigurationSupport
介面messageconverter不起作用。