您的位置:首页 > 编程语言 > Java开发

SpringBoot9-Spring MVC-Spring MVC高级配置

2017-07-27 22:31 453 查看

一:文件上传

      文件上传是一个项目里经常要用的功能,Spring MVC通过配置一个MultipartResolver来上传文件。

      在Spring的控制器中通过MultipartFile file来接收文件,通过MultipartFile[] files接收多个文件上传。

     下面是示例:

1,添加文件上传依赖:

<!--文件上传依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!--非必须,可简化I/O操作-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>


目前完整的pom.xml代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>

<groupId>com.jack</groupId>
<artifactId>springmvc1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<!--基本属性配置-->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--WEB的属性配置-->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>3.1.0</servlet.version>
<!--spring基本属性的配置-->
<spring-framework.version>4.3.9</spring-framework.version>
<!--Logging日志的基本属性配置-->
<logback.version>1.2.3</logback.version>
<slf4j.version>1.7.25</slf4j.version>
</properties>

<!--依赖配置-->
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>

<!--spring mvc的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}.RELEASE</version>
</dependency>

<!--其他web依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>

<!--spring and transactions-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}.RELEASE</version>
</dependency>

<!--使用SLF4J和LogBack作为日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
</dependency>
<!--添加jackson依赖,获得对象和josn或xml之间的转换-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.9</version>
</dependency>

<!--文件上传依赖--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <!--非必须,可简化I/O操作--> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency>

</dependencies>

<build>
<!--插件-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>

</plugins>
</build>

</project>


2,上传页面

    在src/main/resources/views下新建upload.jsp,页面代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8" >
<title>upload page</title>
</head>
<body>
<div class="upload">
<form action="upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/><br/>
<input type="submit" value="上传"/>
</form>
</div>
</body>
</html>


3,添加转向到upload页面的ViewController

/**
* 统一处理没啥业务逻辑处理的controller请求,实现代码的简洁
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
registry.addViewController("/index").setViewName("/index");
registry.addViewController("/toUpload").setViewName("upload");
}


4,MultipartResolver配置

/**
* 配置文件上传Bean
* @return
*/
@Bean
public MultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}


目前spring mvc配置类的代码如下:

package jack.springmvc.config;

import jack.springmvc.interceptor.DemoInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
* Created by jack on 2017/7/16.
*/
@Configuration
@EnableWebMvc //开启Spring MVC支持,若无此句,重写WebMvcConfigurerAdapter方法无效
@ComponentScan("jack.springmvc")
//继承WebMvcConfigurerAdapter类,重写其方法可对Spring MVC进行配置
public class MyMvcConfig extends WebMvcConfigurerAdapter{

/**
* 配置拦截器的Bean
* @return
*/
@Bean
public DemoInterceptor demoInterceptor(){
return new DemoInterceptor();
}

/** * 配置文件上传Bean * @return */ @Bean public MultipartResolver multipartResolver(){ CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(1000000); return multipartResolver; }

/**
* c重写addInterceptors方法,注册拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
registry.addInterceptor(demoInterceptor());
}

@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
//viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//super.addResourceHandlers(registry);
//addResourceLocations指的是文件放置的目录,addResourceHandler指的是对外暴露的访问路径
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
}

/** * 统一处理没啥业务逻辑处理的controller请求,实现代码的简洁 * @param registry */ @Override public void addViewControllers(ViewControllerRegistry registry) { //super.addViewControllers(registry); registry.addViewController("/index").setViewName("/index"); registry.addViewController("/toUpload").setViewName("upload"); }

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
//super.configurePathMatch(configurer);
configurer.setUseSuffixPatternMatch(false);
}
}


5,控制器

package jack.springmvc.controller;

import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

/**
* Created by jack on 2017/7/25.
* 文件上传控制器
*/
@Controller
public class UploadController {
@RequestMapping(value = "/upload",method = RequestMethod.POST)
@ResponseBody
public String upload(MultipartFile file){//使用MultipartFile接受上传的文件
try {
//使用FileUtils.writeByteArrayToFile快速写文件到磁盘
FileUtils.writeByteArrayToFile(new File("F:\\yhcrm/"+file.getOriginalFilename()),file.getBytes());
return "ok";
}catch (Exception e){
e.printStackTrace();
return "wrong";
}
}
}


6,运行程序,在浏览器输入:http://localhost:8080/toUpload,如图:



单击上传,可以在指定的目录下看到上传的文件。

二:自定义HttpMessageConverter

      HttpMessageConverter是用来处理request和response里的数据的。Spring为我们内置了大量的HttpMessageConverter,例如,MappingJackson2HttpMessageConverter,StringHttpMessageConvert等。下面演示自定义的HttpMessageConverter,并主持这个HttpMessageConverter到Spring
MVC。

       示例:

1,自定义HttpMessageConverter

package jack.springmvc.messageconverter;

import jack.springmvc.domain.DemoObj;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.Charset;

/**
* Created by jack on 2017/7/25.
*/
//继承AbstractHttpMessageConverter实现自定义接口
public class MyMessageConverter extends AbstractHttpMessageConverter<DemoObj>{
public MyMessageConverter() {
//新建一个我们自定义的媒体类型application/x-wisely
super(new MediaType("application", "x-wisely", Charset.forName("UTF-8")));
}

/**
* 表明本HttpMessageConverter只处理DemoObj这个类
* @param aClass
* @return
*/
@Override
protected boolean supports(Class<?> aClass) {
return DemoObj.class.isAssignableFrom(aClass);
}

/**
* 重写readInternal方法,处理请求的数据,代码表明处理由"-"隔开的数据,并转成DemoObj的对象
* @param aClass
* @param httpInputMessage
* @return
* @throws IOException
* @throws HttpMessageNotReadableException
*/
@Override
protected DemoObj readInternal(Class<? extends DemoObj> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
String temp = StreamUtils.copyToString(httpInputMessage.getBody(), Charset.forName("UTF-8"));
String[] tempArr = temp.split("-");

return new DemoObj(new Long(tempArr[0]),tempArr[1]);
}

/**
* 重写writeInternal,处理如何输出数据到response,代码中在原样输出前面加上hello:
* @param obj
* @param httpOutputMessage
* @throws IOException
* @throws HttpMessageNotWritableException
*/
@Override
protected void writeInternal(DemoObj obj, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
String out = "hello :" + obj.getId() + "-" + obj.getName();
httpOutputMessage.getBody().write(out.getBytes());
}
}


2,配置。在addViewControllers中添加ViewController映射页面访问演示页面,代码如下:

registry.addViewController("/converter").setViewName("/converter");


addViewControllers方法中目前所有的代码如下:

/**
* 统一处理没啥业务逻辑处理的controller请求,实现代码的简洁
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
registry.addViewController("/index").setViewName("/index");
registry.addViewController("/toUpload").setViewName("upload");
registry.addViewController("/converter").setViewName("/converter");
}


    重写extendMessageConverters方法:

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//super.extendMessageConverters(converters);
converters.add(converter());
}

@Bean
public MyMessageConverter converter(){
return new MyMessageConverter();
}


spring mvc目前所有的配置如下:

package jack.springmvc.config;

import jack.springmvc.interceptor.DemoInterceptor;
import jack.springmvc.messageconverter.MyMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.util.List;

/**
* Created by jack on 2017/7/16.
*/
@Configuration
@EnableWebMvc //开启Spring MVC支持,若无此句,重写WebMvcConfigurerAdapter方法无效
@ComponentScan("jack.springmvc")
//继承WebMvcConfigurerAdapter类,重写其方法可对Spring MVC进行配置
public class MyMvcConfig extends WebMvcConfigurerAdapter{

/**
* 配置拦截器的Bean
* @return
*/
@Bean
public DemoInterceptor demoInterceptor(){
return new DemoInterceptor();
}

/** * 配置文件上传Bean * @return */ @Bean public MultipartResolver multipartResolver(){ CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(1000000); return multipartResolver; }

/**
* c重写addInterceptors方法,注册拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
registry.addInterceptor(demoInterceptor());
}

@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
//viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//super.addResourceHandlers(registry);
//addResourceLocations指的是文件放置的目录,addResourceHandler指的是对外暴露的访问路径
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
}

/** * 统一处理没啥业务逻辑处理的controller请求,实现代码的简洁 * @param registry */ @Override public void addViewControllers(ViewControllerRegistry registry) { //super.addViewControllers(registry); registry.addViewController("/index").setViewName("/index"); registry.addViewController("/toUpload").setViewName("upload"); registry.addViewController("/converter").setViewName("/converter"); }

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
//super.configurePathMatch(configurer);
configurer.setUseSuffixPatternMatch(false);
}

/**
* 配置自定义的HttpMessageConverter的bean,在spring mvc里注册HttpMessageConverter有两个方法:
* configureMessageConverters:重载会覆盖掉Spring MVC默认注册的多个HttpMessageConverter
* extendMessageConverters:仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter
* @param converters
*/
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { //super.extendMessageConverters(converters); converters.add(converter()); } @Bean public MyMessageConverter converter(){ return new MyMessageConverter(); }

}


3,编写控制器:

package jack.springmvc.controller;

import jack.springmvc.domain.DemoObj;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* Created by jack on 2017/7/26.
*/
@Controller
public class ConverterController {
//指定返回的媒体类型为我们自定义的媒体类型application/x-wisely
@RequestMapping(value = "/convert",produces = {"application/x-wisely"})
@ResponseBody
public DemoObj convert(@RequestBody DemoObj demoObj){
return demoObj;
}
}


4,演示页面。在src/main/resources下新建converter.jsp,代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=UTF-8" >
<title>HttpMessageConverter Demo</title>
<script src="../assets/js/jquery-3.2.1.js"></script>
</head>
<body>

<div id="resp"></div>
<input type="button" onclick="req();" value="请求"/>

<script>
function req() {
$.ajax({
url: "convert",
data: "1-jack",//主要这里的数据格式,后台处理按此格式处理,用"-"隔开
type: "POST",
contentType:"application/x-wisely",//contentType设置的媒体类型是我们自定义的application/w-wisely
success: function (data) {
$("#resp").html(data);
}
});
}
</script>
</body>
</html>


5,运行

        在浏览器输入:http://localhost:8080/converter,如下图:



点击请求按钮,做如下规则:



页面效果如下:



三:服务器端推送技术

       服务端推送技术在日常开发中较为常用,早期很多人采用ajax向服务器轮询消息,使浏览器尽可能第一时间获得服务端的消息,因为这种方式的轮询频率不好控制,所以大大增加了服务端的压力。

      下面的服务器端推送方案都是基于:当客户端向服务端发送请求,服务端会抓住这个请求不放,等有数据更新的时候才返回给客户端,当客户端接收到消息后,在向服务端发送请求,周而复使。这种方式的好处是减少了服务端的请求数量,大大减少了服务器的压力。

       除了服务器推送技术以外,还有另外一个双向通信的技术一WebSocket。

       下面基于SSE(Server Send Event服务端发送事件)的服务器端推送和基于Servlet3.0+的异步方法特性,其中第一种方式需要新式浏览器的支持,第二种是跨浏览器的。

     1,SSE

   1)演示控制器

package jack.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Random;

/**
* Created by jack on 2017/7/26.
*/
@Controller
public class SseController {
/**
* 这里使用输出媒体类型为text/event-stream,这是服务器端SSE的支持
* @return
*/
@RequestMapping(value = "/push",produces="text/event-stream;charset=UTF-8")
public @ResponseBody String push(){
Random r = new Random();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "data:Testing 1,2,3->"+r.nextInt()+"\n\n";
}
}


2)演示页面,在src/main/resources/views下新建sse.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SSE Demo</title>
</head>
<body>
<div id="msgFromPush"></div>

<script type="text/javascript"
src="<c:url value="../assets/js/jquery-3.2.1.js" />"></script>
<script type="text/javascript">
if (!!window.EventSource) { //EventSource是SSE的客户端.此时说明浏览器支持EventSource对象
var source = new EventSource('push');//发送消息
s = '';
source.addEventListener('message', function(e) {
s += e.data + "<br/>";
$("#msgFromPush").html(s);
});//添加客户端的监听

source.addEventListener('open', function(e) {
console.log("连接打开");
}, false);

source.addEventListener('error',function(e){
if(e.readyState==EventSource.CLOSED){
console.log("连接关闭");
}else{
console.log(e.readyState);
}
});
}else{
console.log("您的浏览器不支持SSE");
}
</script>
</body>
</html>


3)配置

添加转向sse.jsp页面的映射:

registry.addViewController("/sse").setViewName("/sse");


4)运行

      在浏览器输入:http://localhost:8080/sse,如下图所示:



2,Servlet3.0+异步方法处理

1),开启异步方法支持:

package jack.springmvc.config;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

/**
* Created by jack on 2017/7/16.
* web配置
*/
/*
WebApplicationInitializer是spring提供用来配置Servlet3.0+配置的接口,从而实现了替代web.xml的位置。实现此接口将会
自动被SpringServletContainerInitializer(用来启动Servlet3.0容器)获取到
*/
public class WebInitializer implements WebApplicationInitializer{
public void onStartup(ServletContext servletContext) throws ServletException {
//新建WebApplicaitonContext,注册配置类,并将其和当前的servletContext关联
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(MyMvcConfig.class);
ctx.setServletContext(servletContext);

//注册Spring MVC的DispatcherServlet
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher",new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setLoadOnStartup(1);
servlet.setAsyncSupported(true);//开启异步方法支持
}
}


2)演示控制器
package jack.springmvc.controller;

import jack.springmvc.service.PushService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;

/**
* Created by jack on 2017/7/27.
*/
@Controller
public class AsyncController {
/**
* 异步任务的实现是通过控制器从另外一个线程返回一个DeferredResult,这里的DeferredResult
* 是从pushService中获得的
*/
@Autowired
PushService pushService;
@RequestMapping(value = "/defer")
@ResponseBody
public DeferredResult<String> deferredCall(){
//返回给客户端的DeferredResult
return pushService.getAsyncUpdate();
}
}


3)定时任务

package jack.springmvc.service;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;

/**
* Created by jack on 2017/7/27.
*/
@Service
public class PushService {
//PushService里产生DeferredResult给控制器使用
private DeferredResult<String> deferredResult;
public DeferredResult<String> getAsyncUpdate(){
deferredResult = new DeferredResult<String>();
return deferredResult;
}

//通过@Scheduled注解定时更新DeferredResult
@Scheduled(fixedDelay = 5000)
public void refresh(){
if (deferredResult != null) {
deferredResult.setResult(new Long(System.currentTimeMillis()).toString());
}
}

}


4)演示页面

  在src/main/resources/views下新建async.jsp,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>servlet async support</title>
</head>
<body>
<div id="msgFromPush"></div>

<script type="text/javascript"
src="<c:url value="../assets/js/jquery-3.2.1.js" />"></script>
<script type="text/javascript">
deferred();//页面打开就向后台发送请求
function deferred() {
$.get('defer',function (data) {
console.log(data);//在浏览器控制台输出服务端推送的数据
deferred();//一次请求完成以后在向后台发送请求
});
}
</script>
</body>
</html>

5)配置

    在MyMvcConfig上开始计划任务的支持,使用@EnableScheduling:

package jack.springmvc.config;

import jack.springmvc.interceptor.DemoInterceptor;
import jack.springmvc.messageconverter.MyMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.util.List;

/**
* Created by jack on 2017/7/16.
*/
@Configuration
@EnableWebMvc //开启Spring MVC支持,若无此句,重写WebMvcConfigurerAdapter方法无效
@ComponentScan("jack.springmvc")
@EnableScheduling //开启计划任务的支持
//继承WebMvcConfigurerAdapter类,重写其方法可对Spring MVC进行配置
public class MyMvcConfig extends WebMvcConfigurerAdapter{

/**
* 配置拦截器的Bean
* @return
*/
@Bean
public DemoInterceptor demoInterceptor(){
return new DemoInterceptor();
}

/** * 配置文件上传Bean * @return */ @Bean public MultipartResolver multipartResolver(){ CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(1000000); return multipartResolver; }

/**
* c重写addInterceptors方法,注册拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
registry.addInterceptor(demoInterceptor());
}

@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
//viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//super.addResourceHandlers(registry);
//addResourceLocations指的是文件放置的目录,addResourceHandler指的是对外暴露的访问路径
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
}

/**
* 统一处理没啥业务逻辑处理的controller请求,实现代码的简洁
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
registry.addViewController("/index").setViewName("/index");
registry.addViewController("/toUpload").setViewName("upload");
registry.addViewController("/converter").setViewName("/converter");
registry.addViewController("/sse").setViewName("/sse");
registry.addViewController("/async").setViewName("/async");
}

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
//super.configurePathMatch(configurer);
configurer.setUseSuffixPatternMatch(false);
}

/**
* 配置自定义的HttpMessageConverter的bean,在spring mvc里注册HttpMessageConverter有两个方法:
* configureMessageConverters:重载会覆盖掉Spring MVC默认注册的多个HttpMessageConverter
* extendMessageConverters:仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter
* @param converters
*/
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { //super.extendMessageConverters(converters); converters.add(converter()); } @Bean public MyMessageConverter converter(){ return new MyMessageConverter(); }

}


     上面了添加viewController:
registry.addViewController("/async").setViewName("/async");

6)运行

在浏览器输入:http://localhost:8080/async,打开f12查看,如下图所示:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息