Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置

4.5.1文件上传配置
文件上传是一个项目里经常要用的功能,Spring MVC通过配置一个MultipartResolver来上传文件。
在Spring的控制器中,通过MultipartFile file 来接收文件,通过MultipartFile[] files 接收多个文件上传。
示例
(1)添加文件上传依赖。

	
	
		commons-fileupload	
		commons-fileupload
		1.3.1
	
	
	
		commons-io
		commons-io
		2.3
	

(2)上传页面。在 src/main/resources/views下载新建 upload.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




upload page




(3)添加转向到upload页面的ViewController。

	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addViewController("/index").setViewName("/index");
		registry.addViewController("/toUpload").setViewName("/upload");
	}

(4)MultipartResolver配置。

	@Bean
	public MultipartResolver multipartResolver(){
		CommonsMultipartResolver multipartResolver = 
				new CommonsMultipartResolver();
		multipartResolver.setMaxUploadSize(1000000);
		return multipartResolver;
	}

(5)控制器。

package com.wisely.highlight_springmvc4.web.ch4_5;

import java.io.File;
import java.io.IOException;

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;

@Controller
public class UploadController {

	@RequestMapping(value ="/upload",method=RequestMethod.POST)
	public @ResponseBody String upload(MultipartFile file){ //使用MultipartFile接受上传的文件
		try {
			FileUtils.writeByteArrayToFile(new File("d:/upload/"+file.getOriginalFilename()),
					file.getBytes());  //使用FileUtils.writeByteArrayToFile快速写文件到磁盘。
			return "ok";
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "wrong";
		}
	}
}

(6)运行。访问http:localhost:8080/highlight_springmvc4/toUpload,如图
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190116104431304.pngSpring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第1张图片
单击“上传”按钮后,查看d:\upload文件夹,如图

Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第2张图片
4.5.2 自定义HttpMessageConverter
HttpMessageConverter是用来处理request和response里的数据的。Spring为我们内置大量的HtpMessageConverter,例如,MappingJackson2HttpMessageConverter、StringHttpMessageConverter等。本节将演示自定义的HttpMessageConverter,并注册这个HttpMessageConverter到Spring MVC。
示例
(1)自定义HttpMessageConverter。

package com.wisely.highlight_springmvc4.messageconverter;

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

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 com.wisely.highlight_springmvc4.domain.DemoObj;

public class MyMessageConverter extends AbstractHttpMessageConverter {//继承AbstractHttpMessageConverter接口来实现自定义的HttpMessageConverter。
	
	public MyMessageConverter(){
		super(new MediaType("application","x-wisely",Charset.forName("UTF-8"))); //新建一个我们自定义的媒体类型application/x-wisely		
	}

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

	/**
	 * 重写readInternal方法,处理请求的数据。代码表明我们处理由“-”隔开的数据,并转成DemoObj的对象。
	 */
	@Override
	protected DemoObj readInternal(Class clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException {
		String temp = StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"));
		String[] tempArr = temp.split("-");
		
		return new DemoObj(new Long(tempArr[0]),tempArr[1]);
	}
	/**
	 * 重写writeInterNal,处理如何输出数据到response。此例中,我们在原样输出前面加上“hello:”。
	 */
	@Override
	protected void writeInternal(DemoObj obj, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException {
		String out = "hello:" +obj.getId() + "-" +obj.getName();
		outputMessage.getBody().write(out.getBytes());
		
	}
	
	
}

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

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

配置自定义的HttpMessageConverter的Bean,在Spring MVC里注册HttpMessageConverter有两个方法:

  1. configureMessageConverters:重载会覆盖掉Spring MVC默认注册的多个HttpMessageConverter。
  2. extendMessageConverters:仅添加一个自定义的HttpMessageConverter,不覆盖默认注册的HttpMessageConverter。

所以在此例中我们重写extendMessageConverters:

	@Override
	public void extendMessageConverters(List> converters) {
		converters.add(converter());
	}
	@Bean
	public MyMessageConverter converter(){
		return new MyMessageConverter();
	}

(3)演示控制器。

package com.wisely.highlight_springmvc4.web.ch4_5;

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;

import com.wisely.highlight_springmvc4.domain.DemoObj;

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

(4)演示页面。 在src/main/resources下新建 conventer.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




upload page



(5)运行。访问http://localhost:8080/highlight_springmvc4/converter
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第3张图片
单击“请求”按钮,做如下观察。
请求类型如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第4张图片
后台获得我们自定义的数据格式,如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第5张图片
页面效果如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第6张图片
4.5.3服务器端推送技术
服务器端推送技术在我们日常开发中较为常用,可能早期很多人的解决方案是使用Ajax向服务器轮询消息,使浏览器尽可能第一时间获得服务端的消息,因为这种方式的轮询频率不好控制,所以大增加了服务端的压力。
本节的服务器端推送方案都是基于:当客户端向服务端发送请求,服务端会抓住这个请求不放,等有数据更新是时候才返回给客户端,当客户端接收到消息后,再向服务端发送请求,周而复始。这种方式的好处是减少了服务器的请求数量,大大减少了服务器的压力。
除了服务器端推送技术以外,还有一个另外的双向通信的技术–WebSocket,我们将在后面章节。
本节将提供基于SSE(Server Send Event 服务端发送事件)的服务器端推送和基于Servlet3.0+的异步方法特性,其中第一种方式需要新式浏览器的支持,第二种方式是跨浏览器的。
1.SSE
(1)演示控制器。

package com.wisely.highlight_springmvc4.web.ch4_5;

import java.util.Random;

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

@Controller
public class SseController {
	
	@RequestMapping(value = "/push" , produces="text/event-stream")  //注意,这里使用输出的媒体类型为 text/event-stream,这是服务器端SSE的支持,本例演示每5秒钟向浏览器推送随机消息。
	public @ResponseBody String push(){
		Random r = new Random();
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "data:Testing 1,2,3"+r.nextInt() +"\n\n";
	}
}

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

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




SEE Demo



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

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

(4)运行。访问http://localhost:8080/highlight_springmvc4/see,如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第7张图片
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第8张图片
2.Servlet 3.0+异步方法处理
(1)开启异步方法支持:

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

(2)演示控制器。

package com.wisely.highlight_springmvc4.web.ch4_5;

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;

import com.wisely.highlight_springmvc4.service.PushService;

@Controller
public class AysncController {
	@Autowired
	PushService pushService;
	
	@RequestMapping("/defer")
	@ResponseBody
	public DeferredResult deferredCall(){  //返回给客户端DeferredResult
		return pushService.getAsyncUpdate();
	}
}

(3)定时任务:

package com.wisely.highlight_springmvc4.service;

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

@Service
public class PushService {
	
	private DeferredResult deferredResult;  //在PushService里产生DeferredResult给控制器使用,通过@Scheduled注解的方法定时更新DeferredReslt。
	
	
	public DeferredResult getAsyncUpdate(){
		deferredResult = new DeferredResult();
		return deferredResult;
	}
	@Scheduled(fixedDelay = 5000)
	public void refresh(){
		if(deferredResult != null){
			deferredResult.setResult(new Long(System.currentTimeMillis()).toString());
		}
	}
}

(4)演示页面
在 src/main/views下新建 async.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




servlet async support






(5)配置。
在MyMvcConfig上开始计划任务的支持,使用@EnableScheduling:

@Configuration
@EnableWebMvc //开启SpringMVC支持,若无此名,重写WebMvcConfigurerAdapter方法无效。
@EnableScheduling
@ComponentScan("com.wisely.highlight_springmvc4")

添加viewController:

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

(6)运行。访问http://localhost:8080/highlight_springmvc4/async,如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第9张图片
控制台输出如图
Spring Boot实战(四)Spring MVC基础 4.5 Spring MVC的高级配置_第10张图片

你可能感兴趣的:(Spring,Boot,实战)