栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot——整合Web开发(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot——整合Web开发(一)

SpringBoot——整合Web开发(一)

一、返回JSON数据二、静态资源访问三、文件上传

一、返回JSON数据
    默认实现
    JSON是目前主流的前后端数据创输方式,SpringMVC中使用消息转换器HttpMessageConverter对JSON的转换提供了很好的支持,在SpringBoot中更进一步,对相关配置做了进一步简化。默认情况下
    添加依赖
        
            org.springframework.boot
            spring-boot-starter-web
        

这个依赖中默认加入了jackson-databind作为JSON处理器,此时不需要添加额外的JSON处理器就能返回一段JSON了。


如果需要频繁的使用@ResponseBody注解,可以采用@RestController组合注解代替@Controller和@ResponseBody
这是通过Spring中默认提供的MappingJackson2HttpMessageConverter来实现的。

    自定义转换器
    常见的JSON处理器除了jackson-databind之外,还有Gson和fastjson。

使用Gson
Gson是Google是一个开源JSON解析框架。使用GSON,需要除去默认的jackson-databind,然后添加Gson依赖。

        
            org.springframework.boot
            spring-boot-starter-web
            
                
                    com.fasterxml.jackson.core
                    jackson-databind
                
            
        
        
        
            com.google.code.gson
            gson
        

由于SpringBoot中默认提供了Gson的自动转换类GsonHttpMessageConvertersConfiguration,因此Gson的依赖添加成功后,可以像使用jackson-databind那样直接使用Gson。如果对日期数据进行格式化,那么需要开发者自动义HttpMessageConverter,自定义HttpMessageConverter可以通过如下方式:
首先GsonHttpMessageConvertersConfiguration中的一段源码:

    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnBean({Gson.class})
    @Conditional({GsonHttpMessageConvertersConfiguration.PreferGsonOrJacksonAndJsonbUnavailableCondition.class})
    static class GsonHttpMessageConverterConfiguration {
        GsonHttpMessageConverterConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
            GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
            converter.setGson(gson);
            return converter;
        }
    }

@ConditionalOnMissingBean注解表示当前项目中没有提供GsonHttpMessageConverter时才会使用默认的GsonHttpMessageConverter所以只需要提供一个GsonHttpMessageConverter即可。

@Configuration
public class gsonConverter  {
    @Bean
    GsonHttpMessageConverter gsonHttpMessageConverter() {
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setDateFormat("yyyy-MM-dd");

        gsonBuilder.excludeFieldsWithModifiers(Modifier.PROTECTED);
        Gson gson = gsonBuilder.create();
        converter.setGson(gson);
        return converter;
    }
}

解释:

提供一个 GsonHttpMessageConverter 的实例设置Gson解析时日期的格式设置Gson解析时修饰符为PROTECTED的字段被过滤掉创建Gson对象放入GsonHttpMessageConverter 的实例并返回converter

Book修改如下price改为protected类型。

使用fastjson
fastjson是阿里巴巴的一个开源JSON框架,是目前JSON解析速度最快的开源框架,该框架也可以集成到Spring Boot中。不同于Gson,fastjson继承完成之后并不能立马使用。需要开发者提供相应的HttpMessageConverter后才能使用,集成fastjson的步骤如下:

  
            org.springframework.boot
            spring-boot-starter-web
            
                
                    com.fasterxml.jackson.core
                    jackson-databind
                
            
        
        
       

@Configuration
public class fastjsonConverter {
    @Bean
    FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setCharset(Charset.forName("GBK"));
        fastJsonConfig.setDateFormat("yyyy-MM-dd");
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteClassName,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty
                );
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        return fastJsonHttpMessageConverter;
    }
}


解析:配置了JSON解析过程的一些细节,例如日期格式、数据编码、是否在生成的JSON中输出类名、是否输出value为null的数据、生成的JSON格式化、空集合输出[]而非null、空字符串输出“”而非null等基本配置

fastJson配置另一种方式
在SpringBoot项目中,当开发者引入spring-boot-starter-web依赖之后,该依赖又依赖了spring-boot-autoconfigure,在这个自动化配置中,有一个WebMvcAutoConfiguration类提供了对SpringMVC的基本配置,如果某一项自动化配置不满足开发需求,可以针对该项自定义配置,只需要实现WebMvcConfigurer接口即可(在Spring5.0之前是通过继承WebMvcConfigurerAdapter类来实现的)

package com.example.demo.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.Charset;
import java.util.List;

@Configuration
public class fastjsonMvcConverter implements WebMvcConfigurer {

    public void configureMessageConverters(List> converters) {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setCharset(Charset.forName("GBK"));
        fastJsonConfig.setDateFormat("yyyy-MM-dd");
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteClassName,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullStringAsEmpty
        );
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastJsonHttpMessageConverter);
    }
}

gson也可以使用实现WebMvcConfigurer接口这种方式

package com.example.demo.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.lang.reflect.Modifier;
import java.util.List;

@Configuration
public class fastjsonMvcConverter implements WebMvcConfigurer {

   public void configureMessageConverters(List> converters) {
       GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
       GsonBuilder gsonBuilder = new GsonBuilder();
       gsonBuilder.setDateFormat("yyyy-MM-dd");
       gsonBuilder.excludeFieldsWithModifiers(Modifier.PROTECTED);
       Gson gson = gsonBuilder.create();
       converter.setGson(gson);
       converters.add(converter);
   }
}

此时的效果如下:

上述结果中发现转换并没有生效。
原因如下:

这是因为SpringBoot在项目中没有GsonHttpMessageConverter时,SpringBoot自己会提供一个GsonHttpMessageConverter,所以此时需要替换掉原有的GsonHttpMessageConverter。代码如下:

package com.example.demo.config;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.lang.reflect.Modifier;
import java.util.List;

@Configuration
public class fastjsonMvcConverter implements WebMvcConfigurer {

    public void configureMessageConverters(List> converters) {
        converters.remove(7);
        converters.remove(7);
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setDateFormat("yyyy-MM-dd");
        gsonBuilder.excludeFieldsWithModifiers(Modifier.PROTECTED);
        Gson gson = gsonBuilder.create();
        converter.setGson(gson);
        converters.add(converter);
    }
}

二、静态资源访问
    默认策略
    SpringBoot中对于SpringMVC的自动化配置都在WebMvcAutoConfiguration类中,因此对于默认的静态资源过滤策略可以从这个类一窥究竟。
    在WebMvcAutoConfiguration类中有一个静态内部类WebMvcAutoConfigurationAdapter,实现了WebMvcConfigurer接口。WebMvcConfigurer接口中有一个方法addResourceHandlers,是用来配置静态资源过滤的。方法在WebMvcAutoConfigurationAdapter类中得到了实现。
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, "/webjars/**", "classpath:/meta-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }

                });
            }
        }

SpringBoot在这里进行了默认的静态资源过滤位置,其中staticPathPattern默认定义在WebMvcProperties中定义内容如下:

staticLocation获取到的默认静态资源位置定义在Resources resourceProperties中代码如下:


注意:按照定义的顺序,静态资源位置的优先级依次降低。

如果使用Idea创建SpringBoot项目,就会默认创建出classpath:/static/目录

    自定义策略
    如果默认的静态资源策略不能满足开发需求,也可以自定义静态资源过滤策略,自定义静态资源过滤策略有以下两种方式:

在配置文件中定义
可以在application.properties中直接定义过滤规则和静态,代码如下:

spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/ ---过时啦

Java编码定义
只需要实现WebMvcConfigurer接口即可,然后实现该接口的addResourceHandlers方法即可。

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

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

}

三、文件上传

java中的文件上传一共涉及两个组件,一个是CommonsMultipartResolver,另一个是StandardServletMuttipartResolver,其中CommonsMultipartResolver使用commons-fileupload来处理multipart请求,而StandardServletMultipartResolver则是基于Servlet3.0来处理multipart请求的,因此若使用StandardServletMultipartResolver,则不需要添加额外的jar包。Tomcat7.0开始就支持Servlet3.0了,而SpringBoot 2.0.4内嵌的Tomcat为Tomcat 8.5.32,因此可以直接使用StandardServletMultipartResovler。而SpringBoot提供的文件上传自动化配置类MultipartAutoConfiguration中,默认也是采用StandardServletMultipartResovler。

public class MultipartAutoConfiguration {
	....
    @Bean(
        name = {"multipartResolver"}
    )
    @ConditionalOnMissingBean({MultipartResolver.class})
    public StandardServletMultipartResolver multipartResolver() {
        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
        return multipartResolver;
    }
}

根据这里的配置可以看出,如果开发者没有提供MultipartResolver,那么默认采用的MultipartResolver就是StandardServletMultipartResolver。因此,在SpringBoot中上传文件可以做到零配置。

单文件上传

@RestController
public class FileUploadController {
    SimpleDateFormat simpleDataFormat = new SimpleDateFormat("yyyy-MM-dd");

    @PostMapping("/upload")
    //可以使用@RequestPart
    public String upload(@RequestParam("uploadfile") MultipartFile multipartFile, HttpServletRequest request) throws IOException {
        String filepath = "C:" + File.separator + "Users" + File.separator + "tiaoxiaozi" + File.separator + "Desktop" + File.separator + "uploadFile" + File.separator + "aa" + File.separator;
        String format = simpleDataFormat.format(new Date());
        File folder =  new File(filepath + format);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        String uploadfile = request.getParameter("uploadfile");
        String oldName = multipartFile.getOriginalFilename();
        String oldName_org = oldName.substring(0, oldName.indexOf("."));
        String uuid = UUID.randomUUID().toString();
        String newName = uuid + oldName.substring(oldName.indexOf("."));
        multipartFile.transferTo(new File( folder , newName));
        return "上传成功";
    }

@RequestParam注释还可用于将“多部分/表单数据”请求的一部分与支持相同方法参数类型的方法参数相关联。主要区别在于,当方法参数不是字符串或原始多部分文件/部分时,@RequestParam依赖于通过注册转换器或PropertyEditor进行的类型转换,而RequestPart依赖于HttpMessageConverters,同时考虑到请求部分的“内容类型”头。RequestParam可能与name-value表单字段一起使用,而RequestPart可能与包含更复杂内容的部分(例如JSON、XML)一起使用。

spring.servlet.multipart.enabled=true //是否开启文件上传支持,默认为true
spring.servlet.multipart.file-size-threshold=0 //文件写入磁盘的阈值,默认为0
spring.servlet.multipart.location=E:\temp  // 上传文件的临时保存位置
spring.servlet.multipart.max-file-size=1MB // 上传的单个文件的最大大小 默认为1MB
spring.servlet.multipart.max-request-size=10MB // 多文件上传时的总大小,默认为10MB
spring.servlet.multipart.resolve-lazily=true // 文件是否延迟解析,默认为false

多文件上传

@RestController
public class FileUploadController {
    SimpleDateFormat simpleDataFormat = new SimpleDateFormat("yyyy-MM-dd");

    @PostMapping("/upload")
    //可以使用@RequestPart
    public String upload(@RequestParam("uploadfile") MultipartFile[] multipartFile, HttpServletRequest request) throws IOException {
        String filepath = "C:" + File.separator + "Users" + File.separator + "tiaoxiaozi" + File.separator + "Desktop" + File.separator + "uploadFile" + File.separator + "aa" + File.separator;
        String format = simpleDataFormat.format(new Date());
        File folder =  new File(filepath + format);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        String uploadfile = request.getParameter("uploadfile");
        for (int i = 0; i < multipartFile.length; i++) {
            String oldName = multipartFile[i].getOriginalFilename();
            String oldName_org = oldName.substring(0, oldName.indexOf("."));
            String uuid = UUID.randomUUID().toString();
            String newName = uuid + oldName.substring(oldName.indexOf("."));
            multipartFile[i].transferTo(new File( folder , newName));
        }


        return "上传成功";
    }
}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704605.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号