`

spring优秀工具类---1

阅读更多

Spring 不但提供了一个功能全面的应用开发框架,本身还拥有众多可以在程序编写时直接使用的工具类,您不但可以在 Spring 应用中使用这些工具类,也可以在其它的应用中使用,这些工具类中的大部分是可以在脱离 Spring 框架时使用的。了解 Spring 中有哪些好用的工具类并在程序编写时适当使用,将有助于提高开发效率、增强代码质量。

在这个分为两部分的文章中,我们将从众多的 Spring 工具类中遴选出那些好用的工具类介绍给大家。第 1 部分将介绍与文件资源操作,第2部分中将介绍 Web 相关的工具类,第3部分中将介绍特殊字符转义和方法入参检测工具类。

  

文件资源操作

      文件资源的操作是应用程序中常见的功能,如当上传一个文件后将其保存在特定目录下,从指定地址加载一个配置文件等等。我们一般使用 JDK 的 I/O 处理类完成这些操作,但对于一般的应用程序来说,JDK 的这些操作类所提供的方法过于底层,直接使用它们进行文件操作不但程序编写复杂而且容易产生错误。相比于 JDK 的 File,Spring 的 Resource 接口(资源概念的描述接口)抽象层面更高且涵盖面更广,Spring 提供了许多方便易用的资源操作工具类,它们大大降低资源操作的复杂度,同时具有更强的普适性。这些工具类不依赖于 Spring 容器,这意味着您可以在程序中象一般普通类一样使用它们。



加载文件资源

     Spring 定义了一个 org.springframework.core.io.Resource 接口,Resource 接口是为了统一各种类型不同的资源而定义的,Spring 提供了若干 Resource 接口的实现类,这些实现类可以轻松地加载不同类型的底层资源,并提供了获取文件名、URL 地址以及资源内容的操作方法。



访问文件资源

假设有一个文件地位于 Web 应用的类路径下,您可以通过以下方式对这个文件资源进行访问:

•通过 FileSystemResource 以文件系统绝对路径的方式进行访问;
•通过 ClassPathResource 以类路径的方式进行访问;
•通过 ServletContextResource 以相对于Web应用根目录的方式进行访问。
     相比于通过 JDK 的 File 类访问文件资源的方式,Spring 的 Resource 实现类无疑提供了更加灵活的操作方式,您可以根据情况选择适合的 Resource 实现类访问资源。下面,我们分别通过 FileSystemResource 和 ClassPathResource 访问同一个文件资源:

Java代码
1.package com.baobaotao.io;  
2.import java.io.IOException;  
3.import java.io.InputStream;  
4.import org.springframework.core.io.ClassPathResource;  
5.import org.springframework.core.io.FileSystemResource;  
6.import org.springframework.core.io.Resource;  
7.public class FileSourceExample {  
8.    public static void main(String[] args) {  
9.        try {  
10.            String filePath =   
11.            "D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt";  
12.            // ① 使用系统文件路径方式加载文件  
13.            Resource res1 = new FileSystemResource(filePath);   
14.            // ② 使用类路径方式加载文件  
15.            Resource res2 = new ClassPathResource("conf/file1.txt");  
16.            InputStream ins1 = res1.getInputStream();  
17.            InputStream ins2 = res2.getInputStream();  
18.            System.out.println("res1:"+res1.getFilename());  
19.            System.out.println("res2:"+res2.getFilename());  
20.        } catch (IOException e) {  
21.            e.printStackTrace();  
22.        }  
23.    }  
24.} 
package com.baobaotao.io;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class FileSourceExample {
    public static void main(String[] args) {
        try {
            String filePath =
            "D:/masterSpring/chapter23/webapp/WEB-INF/classes/conf/file1.txt";
            // ① 使用系统文件路径方式加载文件
            Resource res1 = new FileSystemResource(filePath);
            // ② 使用类路径方式加载文件
            Resource res2 = new ClassPathResource("conf/file1.txt");
            InputStream ins1 = res1.getInputStream();
            InputStream ins2 = res2.getInputStream();
            System.out.println("res1:"+res1.getFilename());
            System.out.println("res2:"+res2.getFilename());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}     在获取资源后,您就可以通过 Resource 接口定义的多个方法访问文件的数据和其它的信息:如您可以通过 getFileName() 获取文件名,通过 getFile() 获取资源对应的 File 对象,通过 getInputStream() 直接获取文件的输入流。此外,您还可以通过 createRelative(String relativePath) 在资源相对地址上创建新的资源。

在 Web 应用中,您还可以通过 ServletContextResource 以相对于 Web 应用根目录的方式访问文件资源,如下所示:

Html代码
1.<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> 
2.<jsp:directive.page import="  
3.    org.springframework.web.context.support.ServletContextResource"/> 
4.<jsp:directive.page import="org.springframework.core.io.Resource"/> 
5.<%  
6.    // ① 注意文件资源地址以相对于 Web 应用根路径的方式表示  
7.    Resource res3 = new ServletContextResource(application,   
8.        "/WEB-INF/classes/conf/file1.txt");  
9.    out.print(res3.getFilename());  
10.%> 
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<jsp:directive.page import="
    org.springframework.web.context.support.ServletContextResource"/>
<jsp:directive.page import="org.springframework.core.io.Resource"/>
<%
    // ① 注意文件资源地址以相对于 Web 应用根路径的方式表示
    Resource res3 = new ServletContextResource(application,
        "/WEB-INF/classes/conf/file1.txt");
    out.print(res3.getFilename());
%>
      对于位于远程服务器(Web 服务器或 FTP 服务器)的文件资源,您则可以方便地通过 UrlResource 进行访问。为了方便访问不同类型的资源,您必须使用相应的 Resource 实现类,是否可以在不显式使用 Resource 实现类的情况下,仅根据带特殊前缀的资源地址直接加载文件资源呢?Spring 提供了一个 ResourceUtils 工具类,它支持“classpath:”和“file:”的地址前缀,它能够从指定的地址加载文件资源,请看下面的例子:

Java代码
1.package com.baobaotao.io;  
2.import java.io.File;  
3.import org.springframework.util.ResourceUtils;  
4.public class ResourceUtilsExample {  
5.    public static void main(String[] args) throws Throwable{  
6.        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");  
7.        System.out.println(clsFile.isFile());  
8. 
9.        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt";  
10.        File httpFile = ResourceUtils.getFile(httpFilePath);  
11.        System.out.println(httpFile.isFile());          
12.    }  
13.} 
package com.baobaotao.io;
import java.io.File;
import org.springframework.util.ResourceUtils;
public class ResourceUtilsExample {
    public static void main(String[] args) throws Throwable{
        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt");
        System.out.println(clsFile.isFile());

        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt";
        File httpFile = ResourceUtils.getFile(httpFilePath);
        System.out.println(httpFile.isFile());       
    }
}
      ResourceUtils 的 getFile(String resourceLocation) 方法支持带特殊前缀的资源地址,这样,我们就可以在不和 Resource 实现类打交道的情况下使用 Spring 文件资源加载的功能了。



本地化文件资源

     本地化文件资源是一组通过本地化标识名进行特殊命名的文件,Spring 提供的 LocalizedResourceHelper 允许通过文件资源基名和本地化实体获取匹配的本地化文件资源并以 Resource 对象返回。假设在类路径的 i18n 目录下,拥有一组基名为 message 的本地化文件资源,我们通过以下实例演示获取对应中国大陆和美国的本地化文件资源:

Java代码
1.package com.baobaotao.io;  
2.import java.util.Locale;  
3.import org.springframework.core.io.Resource;  
4.import org.springframework.core.io.support.LocalizedResourceHelper;  
5.public class LocaleResourceTest {  
6.    public static void main(String[] args) {  
7.        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper();  
8.        // ① 获取对应美国的本地化文件资源  
9.        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties",   
10.        Locale.US);  
11.        // ② 获取对应中国大陆的本地化文件资源  
12.        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties",   
13.        Locale.CHINA);  
14.        System.out.println("fileName(us):"+msg_us.getFilename());   
15.        System.out.println("fileName(cn):"+msg_cn.getFilename());  
16.    }  
17.} 
package com.baobaotao.io;
import java.util.Locale;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.LocalizedResourceHelper;
public class LocaleResourceTest {
    public static void main(String[] args) {
        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper();
        // ① 获取对应美国的本地化文件资源
        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties",
        Locale.US);
        // ② 获取对应中国大陆的本地化文件资源
        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties",
        Locale.CHINA);
        System.out.println("fileName(us):"+msg_us.getFilename());
        System.out.println("fileName(cn):"+msg_cn.getFilename());
    }
}
    虽然 JDK 的 java.util.ResourceBundle 类也可以通过相似的方式获取本地化文件资源,但是其返回的是 ResourceBundle 类型的对象。如果您决定统一使用 Spring 的 Resource 接表征文件资源,那么 LocalizedResourceHelper 就是获取文件资源的非常适合的帮助类了。



文件操作

    在使用各种 Resource 接口的实现类加载文件资源后,经常需要对文件资源进行读取、拷贝、转存等不同类型的操作。您可以通过 Resource 接口所提供了方法完成这些功能,不过在大多数情况下,通过 Spring 为 Resource 所配备的工具类完成文件资源的操作将更加方便。



文件内容拷贝

     第一个我们要认识的是 FileCopyUtils,它提供了许多一步式的静态操作方法,能够将文件内容拷贝到一个目标

byte[]、String 甚至一个输出流或输出文件中。下面的实例展示了 FileCopyUtils 具体使用方法:

Java代码
1.package com.baobaotao.io;  
2.import java.io.ByteArrayOutputStream;  
3.import java.io.File;  
4.import java.io.FileReader;  
5.import java.io.OutputStream;  
6.import org.springframework.core.io.ClassPathResource;  
7.import org.springframework.core.io.Resource;  
8.import org.springframework.util.FileCopyUtils;  
9.public class FileCopyUtilsExample {  
10.    public static void main(String[] args) throws Throwable {  
11.        Resource res = new ClassPathResource("conf/file1.txt");  
12.        // ① 将文件内容拷贝到一个 byte[] 中  
13.        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile());  
14.        // ② 将文件内容拷贝到一个 String 中  
15.        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile()));  
16.        // ③ 将文件内容拷贝到另一个目标文件  
17.        FileCopyUtils.copy(res.getFile(),   
18.        new File(res.getFile().getParent()+ "/file2.txt"));  
19. 
20.        // ④ 将文件内容拷贝到一个输出流中  
21.        OutputStream os = new ByteArrayOutputStream();  
22.        FileCopyUtils.copy(res.getInputStream(), os);  
23.    }  
24.} 
package com.baobaotao.io;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.OutputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.FileCopyUtils;
public class FileCopyUtilsExample {
    public static void main(String[] args) throws Throwable {
        Resource res = new ClassPathResource("conf/file1.txt");
        // ① 将文件内容拷贝到一个 byte[] 中
        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile());
        // ② 将文件内容拷贝到一个 String 中
        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile()));
        // ③ 将文件内容拷贝到另一个目标文件
        FileCopyUtils.copy(res.getFile(),
        new File(res.getFile().getParent()+ "/file2.txt"));

        // ④ 将文件内容拷贝到一个输出流中
        OutputStream os = new ByteArrayOutputStream();
        FileCopyUtils.copy(res.getInputStream(), os);
    }
}
    往往我们都通过直接操作 InputStream 读取文件的内容,但是流操作的代码是比较底层的,代码的面向对象性并不强。通过 FileCopyUtils 读取和拷贝文件内容易于操作且相当直观。如在 ① 处,我们通过 FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接将文件内容读到一个 byte[] 中;另一个可用的方法是 copyToByteArray(InputStream in),它将输入流读取到一个 byte[] 中。

     如果是文本文件,您可能希望将文件内容读取到 String 中,此时您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 对 File 进行封装,或使用 InputStreamReader 对 InputStream 进行封装就可以了。



FileCopyUtils 还提供了多个将文件内容拷贝到各种目标对象中的方法,这些方法包括: 





               方法    说明
static void copy(byte[] in, File out)                                         将 byte[] 拷贝到一个文件中
static void copy(byte[] in, OutputStream out)  将 byte[] 拷贝到一个输出流中
static int copy(File in, File out)  将文件拷贝到另一个文件中
static int copy(InputStream in, OutputStream out)  将输入流拷贝到输出流中
static int copy(Reader in, Writer out)  将 Reader 读取的内容拷贝到 Writer 指向目标输出中
static void copy(String in, Writer out)  将字符串拷贝到一个 Writer 指向的目标中





    在实例中,我们虽然使用 Resource 加载文件资源,但 FileCopyUtils 本身和 Resource 没有任何关系,您完全可以在基于 JDK I/O API 的程序中使用这个工具类。



属性文件操作

    我们知道可以通过 java.util.Properties的load(InputStream inStream) 方法从一个输入流中加载属性资源。Spring 提供的 PropertiesLoaderUtils 允许您直接通过基于类路径的文件地址加载属性资源,请看下面的例子:

Java代码
1.package com.baobaotao.io;  
2.import java.util.Properties;  
3.import org.springframework.core.io.support.PropertiesLoaderUtils;  
4.public class PropertiesLoaderUtilsExample {  
5.    public static void main(String[] args) throws Throwable {      
6.        // ① jdbc.properties 是位于类路径下的文件  
7.        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");  
8.        System.out.println(props.getProperty("jdbc.driverClassName"));  
9.    }  
10.} 
package com.baobaotao.io;
import java.util.Properties;
import org.springframework.core.io.support.PropertiesLoaderUtils;
public class PropertiesLoaderUtilsExample {
    public static void main(String[] args) throws Throwable {   
        // ① jdbc.properties 是位于类路径下的文件
        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties");
        System.out.println(props.getProperty("jdbc.driverClassName"));
    }
}
      一般情况下,应用程序的属性文件都放置在类路径下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法显然具有更强的实用性。此外,PropertiesLoaderUtils 还可以直接从 Resource 对象中加载属性资源:





         方法               说明
static Properties loadProperties(Resource resource)  从 Resource 中加载属性
static void fillProperties(Properties props, Resource resource)  将 Resource 中的属性数据添加到一个已经存在的 Properties 对象中





特殊编码的资源

      当您使用 Resource 实现类加载文件资源时,它默认采用操作系统的编码格式。如果文件资源采用了特殊的编码格式(如 UTF-8),则在读取资源内容时必须事先通过 EncodedResource 指定编码格式,否则将会产生中文乱码的问题。

Java代码
1.package com.baobaotao.io;  
2.import org.springframework.core.io.ClassPathResource;  
3.import org.springframework.core.io.Resource;  
4.import org.springframework.core.io.support.EncodedResource;  
5.import org.springframework.util.FileCopyUtils;  
6.public class EncodedResourceExample {  
7.        public static void main(String[] args) throws Throwable  {  
8.            Resource res = new ClassPathResource("conf/file1.txt");  
9.            // ① 指定文件资源对应的编码格式(UTF-8)  
10.            EncodedResource encRes = new EncodedResource(res,"UTF-8");  
11.            // ② 这样才能正确读取文件的内容,而不会出现乱码  
12.            String content  = FileCopyUtils.copyToString(encRes.getReader());  
13.            System.out.println(content);    
14.    }  
15.} 
package com.baobaotao.io;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.FileCopyUtils;
public class EncodedResourceExample {
        public static void main(String[] args) throws Throwable  {
            Resource res = new ClassPathResource("conf/file1.txt");
            // ① 指定文件资源对应的编码格式(UTF-8)
            EncodedResource encRes = new EncodedResource(res,"UTF-8");
            // ② 这样才能正确读取文件的内容,而不会出现乱码
            String content  = FileCopyUtils.copyToString(encRes.getReader());
            System.out.println(content); 
    }
}
     EncodedResource 拥有一个 getResource() 方法获取 Resource,但该方法返回的是通过构造函数传入的原 Resource 对象,所以必须通过 EncodedResource#getReader() 获取应用编码后的 Reader 对象,然后再通过该 Reader 读取文件的内容。



总结

     本文介绍了一些常用的 Spring 工具类,其中大部分 Spring 工具类不但可以在基于 Spring 的应用中使用,还可以在其它的应用中使用。使用 JDK 的文件操作类在访问类路径相关、Web 上下文相关的文件资源时,往往显得拖泥带水、拐弯抹角,Spring 的 Resource 实现类使这些工作变得轻松了许多。

分享到:
评论

相关推荐

    spring-framework-4.3.6.RELEASE

    总结来说,Spring Framework 4.3.6.RELEASE是企业级Java开发的重要工具,其丰富的功能和优秀的社区支持,使得它成为了Java EE领域不可或缺的一部分。无论是在传统的MVC应用、微服务架构还是现代的云原生应用中,...

    spring-framework-4.1.9.RELEASE

    4.1.9.RELEASE是Spring Framework的一个稳定版本,它在继承了前一版本的优秀特性基础上,进一步增强了性能和稳定性,同时引入了一些新的功能和改进。 1. **依赖注入**:Spring的核心特性之一,通过DI,开发者可以将...

    spring-boot-starter-mybatis-spring-boot-1.0.1.zip

    5. **配置实体类**:实体类是与数据库表对应的Java对象,通常我们会使用`@Entity`注解标记,然后通过MyBatis的逆向工程工具自动生成Mapper接口和XML文件。 6. **使用Service层调用**:在Service层,我们可以通过@...

    springcloud-nacos-demo.zip

    而Nacos作为阿里巴巴开源的一款优秀的服务发现与配置管理工具,更是SpringCloud生态中的重要一环。本篇文章将深入探讨如何将SpringCloud与Nacos进行有效整合,通过具体的项目实例——"springcloud-nacos-demo",来...

    spring-framework-master-2018.1.1.zip

    工具模块提供了通用的工具类,如SpEL(Spring Expression Language)用于在运行时查询和操纵对象。消息模块则处理消息传递,如JMS(Java Message Service)的支持。 在2018.1.1这个版本中,Spring可能已经进行了...

    spring-framework-2.5.6

    Spring框架,作为Java开发领域中的核心框架之一,自诞生以来就以其强大的功能、优秀的可扩展性和模块化的结构赢得了广大开发者们的青睐。2.5.6版本是Spring在2008年10月发布的一个稳定版本,它在前一版本的基础上...

    spring源码-2022-08-14spring源码spring源码spring源码

    1. **核心容器**:这是Spring的基础,主要包括BeanFactory和ApplicationContext。BeanFactory负责管理对象(beans)的生命周期和依赖注入,而ApplicationContext提供了更丰富的功能,如消息资源、国际化支持等。 2....

    spring-flex-1.0.1.RELEASE

    1. `flex-messaging-spring`:这是 Spring Flex 的核心模块,它包含 Spring 与 BlazeDS/LCDS 之间的集成,提供 Spring 上下文到 BlazeDS 发布配置的映射。 2. `spring-flex-core`:这个模块包含了处理 Flex 与 ...

    spring-mybatis-spring-1.1.1.zip

    1. **环境准备**:确保已经安装了Java JDK、Maven或Gradle(用于构建工具)以及MySQL或其他数据库。同时,需要在本地环境中配置好相关的环境变量。 2. **创建项目结构**:新建一个Maven或Gradle项目,按照Spring ...

    spring-boot-starter-mybatis-spring-boot-1.3.2.zip

    1. **Spring Boot简介** Spring Boot是由Pivotal团队提供的全新框架,其设计目标是简化新Spring应用的初始搭建以及开发过程。它预设了许多默认配置,如自动配置Spring组件,提供了运行时的“starter”依赖来简化...

    spring-data-mongo配置成功

    确保这些工具类与Spring Data MongoDB的API兼容,可以帮助提升代码的可读性和复用性。 通过以上步骤,你已经成功配置了Spring Data MongoDB,现在可以愉快地进行MongoDB的数据操作了。记住,Spring Data MongoDB的...

    mybatis3+spring+springMVC4整合jar包

    其中,`spring-context`模块提供了与应用程序上下文相关的服务,`spring-core`包含了Spring框架的核心工具类,而`spring-beans`则负责Bean的定义、配置和管理。 3. Spring MVC(spring-web-4.0.2.RELEASE.jar, ...

    spring-data-hadoop-1.0.1.RELEASE.zip

    而提到的"joda-stopwatch.zip",则关联到Joda-Time库中的Stopwatch类,这是一个实用工具类,用于测量代码执行的时间。在Java标准库中,虽然有java.util.Timer和java.lang.System.currentTimeMillis()等方法可以进行...

    spring-boot-paoding-rose.zip

    Paoding-Rose提供了丰富的API和工具,可以方便地集成到Spring Boot的生态中。例如,通过P6Spy监控数据库访问性能,或者使用Paoding-Rose的动态数据源切换功能,以应对复杂多变的业务场景。 总结来说,Spring Boot...

    spring-mybatis-spring-1.0.0.zip

    总之,Spring和MyBatis的整合利用了Spring的强大功能和MyBatis的灵活性,提供了一种优秀的数据访问解决方案。这个资源包的提供,使得开发者能够更便捷地开始这一整合过程,进一步提高开发效率。在实际项目开发中,...

    spring-5.2.6.RELEASE-docs.zip

    Spring 框架由多个模块组成,包括核心容器(Core Container)、数据访问/集成(Data Access/Integration)、Web、AOP(面向切面编程)、工具(Tools)和测试(Test)。其中,核心容器是基础,包含 Beans 和 Core ...

    spring-framework-3.2.0.RELEASE

    4. **更好的性能和诊断**:Spring 3.2 提供了更优秀的性能监控和诊断工具,如应用上下文的初始化时间报告,帮助开发者定位性能瓶颈。 5. **对最新技术的支持**:Spring 3.2 更新了对第三方库的支持,如更新的 JDBC...

    spring-framework-3.2.8.RELEASE 源码

    1. **模块结构**:Spring Framework由多个模块组成,包括Core Container(核心容器)、Data Access/Integration(数据访问/集成)、Web、AOP(面向切面编程)、Instrumentation(工具)和MVC(模型-视图-控制器)。...

    官方原版源码 spring-framework-5.1.16.RELEASE.zip

    总的来说,Spring Framework 5.1.16.RELEASE的源码是一本生动的教科书,它展示了如何设计一个模块化、可扩展的框架,并提供了丰富的工具和API供开发者使用。通过深入研究源码,开发者不仅能提升对Spring Framework的...

Global site tag (gtag.js) - Google Analytics