1. 程式人生 > >springmvc-沒有web.xml和springmvc.xml你還可以執行起來springmvc嗎

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,所以在方法上面就不在配置,直接返回物件型別。

[email protected]配置

@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類的是WebMvcConfigurationSupportWebMvcConfigurer。但是實現了WebMvcConfigurationSupport介面,配置的MessageConverter卻不起作用。實現WebMvcConfigurer可以使用。

好了,就寫到這裡。 我去瞅瞅為啥實現WebMvcConfigurationSupport介面messageconverter不起作用。