Web配置

HeJin大约 3 分钟Spring全家桶SpringBoot精讲细讲

配置资源

项目路径下的资源目录

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/img/**")
                .addResourceLocations("classpath:img/");
    }
}

路径访问:http://localhost:8080/img/1.jpg,既可访问到资源。open in new window

文件系统的资源

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/img/**")
                .addResourceLocations("file:e:/img/");
    }

}

项目的图标等资源文件,一般放在classpath路径下即可。但是用户上传的头像图片等一般很大,需要放在远程的图片服务器,或者放在自己服务器的磁盘上。

配置拦截器

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/img/**")
                .order(1);
    }
}

实现HandlerInterceptor接口自定义拦截器

public class MyInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("进入了拦截器preHandle:" + request.getRequestURI());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        logger.info("进入了拦截器postHandle:" + request.getRequestURI());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("进入了拦截afterCompletion:" + request.getRequestURI());
    }
}

配置消息转化器

导入fastjson依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

重写方法

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            System.out.println(converter);
        }
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 保留map空的字段
                SerializerFeature.WriteMapNullValue,
                // 将String类型的null转成""
                SerializerFeature.WriteNullStringAsEmpty,
                // 将Number类型的null转成0
                SerializerFeature.WriteNullNumberAsZero,
                // 将List类型的null转成[]
                SerializerFeature.WriteNullListAsEmpty,
                // 将Boolean类型的null转成false
                SerializerFeature.WriteNullBooleanAsFalse,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect

        );

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码.相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(mediaTypeList);

        // 将fastjson添加到试图消息转换器列表
        converters.add(converter);
    }
}

我在SpringBoot 2.3.7.RELEASE 这样设置未生效。通过查找资料,打印消息转化器发现配置的自定义的消息转换器在列表最后。根据消息转换器的应用规则,会顺序选择符合要求的消费转换器。MappingJackson2HttpMessageConverter 在 FastJsonJsonpHttpMessageConverter 前面,这样就会使用 MappingJackson2HttpMessageConverter 进行消息转换。

image-20210510164101625
image-20210510164101625

注册Bean的方式

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverter(){
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 保留map空的字段
                SerializerFeature.WriteMapNullValue,
                // 将String类型的null转成""
                SerializerFeature.WriteNullStringAsEmpty,
                // 将Number类型的null转成0
                SerializerFeature.WriteNullNumberAsZero,
                // 将List类型的null转成[]
                SerializerFeature.WriteNullListAsEmpty,
                // 将Boolean类型的null转成false
                SerializerFeature.WriteNullBooleanAsFalse,
                // 避免循环引用
                SerializerFeature.DisableCircularReferenceDetect

        );

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        List<MediaType> mediaTypeList = new ArrayList<>();
        // 解决中文乱码.相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(mediaTypeList);

        return new HttpMessageConverters(converter);
    }
}

这种方式配置后,FastJsonJsonpHttpMessageConverter到了第一个。

image-20210510164630260
image-20210510164630260

解决controller返回中文乱码

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            System.out.println(converter);
            // 解决Controller返回中文乱码问题
            if (converter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
            }
        }
    }
}

配置视图跳转

导入依赖thymeleaf模板引擎

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

配置

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index").setViewName("index");
        registry.addViewController("/login").setViewName("login");
        registry.addViewController("/user").setViewName("user-info");
    }
}

这样配置可以统一对url进行处理,就没有必要写在controller里了。向下面这种写法,比较麻烦,不推荐在controller里面做视图跳转。

// controller里面做视图跳转, 不推荐使用
@Controller
public class UserController {
    @RequestMapping("/index")
    public String index(){
        return "index";
    }
}

thymeleaf模板引擎自动装配,视图解析器默认以classpath:/templates/为prefix,.html为suffix。

image-20210510155551320
image-20210510155551320

配置跨域

controller使用注解配置

@RestController
public class UserController {

    @CrossOrigin({"http://127.0.0.1:555", "http://192.168.1.2:233"})
    @RequestMapping("/api")
    public String api(){
        return "hello cross";
    }
}

config配置类

@Configuration
public class ApplicationConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://127.0.0.1:555", "http://192.168.1.2:233");

        registry.addMapping("/public/**")
                .allowedOrigins("*");
    }
}