目录
二、ContentNegotiatingViewResolver (内容协商视图解析器)
一、官网阅读
官网地址:Spring Boot Reference Documentation
二、ContentNegotiatingViewResolver
(内容协商视图解析器)
ContentNegotiatingViewResolver
实现了视图解析器的类,就可以把它看做视图解析器
ViewResolver 的源码:
public interface ViewResolver {
@Nullable
//resolveViewName 解析视图
View resolveViewName(String viewName, Locale locale) throws Exception;
}
resolveViewName
@Nullable
public View resolveViewName(String viewName, Locale locale) throws Exception {
RequestAttributes attrs = RequestContextHolder.getRequestAttributes();
Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");
List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());
if (requestedMediaTypes != null) {
//getCandidateViews 获取候选视图
List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);
//getBestView 获取最好的视图
View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);
if (bestView != null) {
return bestView;
}
}
String mediaTypeInfo = this.logger.isDebugEnabled() && requestedMediaTypes != null ? " given " + requestedMediaTypes.toString() : "";
if (this.useNotAcceptableStatusCode) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using 406 NOT_ACCEPTABLE" + mediaTypeInfo);
}
return NOT_ACCEPTABLE_VIEW;
} else {
this.logger.debug("View remains unresolved" + mediaTypeInfo);
return null;
}
}
getCandidateViews
private List<View> getCandidateViews(String viewName, Locale locale, List<MediaType> requestedMediaTypes) throws Exception {
List<View> candidateViews = new ArrayList();
if (this.viewResolvers != null) {
Assert.state(this.contentNegotiationManager != null, "No ContentNegotiationManager set");
Iterator var5 = this.viewResolvers.iterator();
while(var5.hasNext()) {
ViewResolver viewResolver = (ViewResolver)var5.next();
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
candidateViews.add(view);
}
Iterator var8 = requestedMediaTypes.iterator();
while(var8.hasNext()) {
MediaType requestedMediaType = (MediaType)var8.next();
List<String> extensions = this.contentNegotiationManager.resolveFileExtensions(requestedMediaType);
Iterator var11 = extensions.iterator();
while(var11.hasNext()) {
String extension = (String)var11.next();
String viewNameWithExtension = viewName + '.' + extension;
view = viewResolver.resolveViewName(viewNameWithExtension, locale);
if (view != null) {
candidateViews.add(view);
}
}
}
}
}
if (!CollectionUtils.isEmpty(this.defaultViews)) {
candidateViews.addAll(this.defaultViews);
}
return candidateViews;
}
//全面扩展SpringMVC
//如果想要diy一些定制化的功能,只需要写这个组件
// 然后将它交给springboot,springboot就睡帮助我们进行自动装配
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//ContentNegotiatingViewResolver 实现了视图解析器的类,就可以把它看做视图解析器
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}
//
public static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String viewName, Locale locale) throws IOException{
return null;
}
}
}
三、Formatter
转换器和格式化器
@Bean
@Override
public FormattingConversionService mvcConversionService() {
Format format = this.mvcProperties.getFormat();
WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
.dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
addFormatters(conversionService);
return conversionService;
}
public DateTimeFormatters dateFormat(String pattern) {
if (isIso(pattern)) {
this.dateFormatter = DateTimeFormatter.ISO_LOCAL_DATE;
this.datePattern = "yyyy-MM-dd";
}
else {
this.dateFormatter = formatter(pattern);
this.datePattern = pattern;
}
return this;
}
四、修改SpringBoot的默认配置
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;
如果有些组件可以存在多个,例如视图解析器,可以将用户配置的和默认的组合起来使用
五、扩展使用SpringMVC
编写类型为WebMvcConfigurer的@Configuration注解类
且不能标注@EnableWebMvc注解;
需要自己写一个;
新建一个包:config,创建类MyMvcConfig;
⚪实现视图跳转
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/zhang").setViewName("test");
}
}