ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring 使用经验谈

2021-07-12 23:32:13  阅读:228  来源: 互联网

标签:return String 经验谈 Spring static str 使用 字符串 public


首先说说大潮流的 Spring Boot。因为项目强制要求的缘故,我不得不将 Spring 升级到 Spring Boot,但我个人觉得,这不但没有必要(不是做微服务),而且有以下几个问题:

  • Boot 采用新的的打包机制,默认生成一个体积非常大的 jar 包。这样导致更新很麻烦,每次上次那么大的 jar 耗时间久(lib 下面的依赖 jar)。以前我更新项目有个技巧,也不是用 war 包(第一次的时候可以是),而是同步本地的到远程的即可,因为本地事实的就是最终编译结果,通过 SFTP 同步两边即可。或者不同步,你知道更新哪个 class/jsp 上传文件即可,名副其实的“增量更新”。现在可好了——上传完整的 jar 包就是“全量更新” 。
  • 同样也正是这个原因,更加网页的静态文件非常不方便。——难道我改 HTML 里面的一个字符就要重新打包 jar 并上传?太不科学了吧!?
  • 由于 Boot 整合了 Tomcat 服务器,那些日志我都不知道哪里看,有肯定是有——那就要重新学习、改变习惯呗。以前的话,用 Tomcat 自带的脚本: catalina.sh run 就可以观察日志,非常方便。

当然,鼎鼎大名的 Boot 不是没有对应的解决方法,百度一下就有了。但鄙人就觉得不太优雅去处理咯。首先 lib/*.jar 可外置游离于 WEB-INF/lib 下面,依靠 Java 层面去指定某个目录,一个项目没啥事,多个项目呢?——这个就花费了人们去管理这个目录的“心智”;其次,前台页面的,也可以游离出去,不是放在 webapps 下面,所以管理维护成本又上升了——我何必那样子呢——老的方法不是很好么。

实事求是地说,Boot 使用起来很方便,简化了很多,但是无非仍是 Spring + Spring MVC 的高层封装,对于搞微服务的 Spring Cloud,那真是刚需。但话又说回来,你不是搞微服务,就是普通的 Web 开发,是不是 Boot 真的差异不大。

话归正题,让我们重新学习 Spring & MVC 吧!

Spring MVC 最小引用

比起我初学 Spring 那时候,Spring 5.x 对依赖简化了不少,我那时候还需要 Common-lang 和 Common Log 之类的,现在不用了。下面是使用 Spring MVC 的最小引用

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>5.3.6</version>
</dependency>

webmvc 自动依赖 web、context 等的包。

启动 Spring

<!-- 启用 Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- JSP 页面编码 -->
<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
        <trim-directive-whitespaces>true</trim-directive-whitespaces>
    </jsp-property-group>
</jsp-config>
<!-- // -->

/WEB-INF 下配置 applicationContext.xml,指定扫描的包:

<!-- 扫描的包 -->
<context:component-scan base-package="net.bingosoft" />

<!--方便 JSP 调用注入的组件-->
<bean class="com.ajaxjs.spring.DiContextUtil" />

Spring MVC 配置

在指定的包之中新建一个 Spring MVC 配置类,继承 BaseWebInitializer

import com.ajaxjs.spring.BaseWebInitializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
public class WebInitializer extends BaseWebInitializer {
}

于是要为 MVC 设一个配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
 	http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<mvc:default-servlet-handler />
</beans>

对 Request、Response 的扩展

web.xml 加入一个过滤器。

<!-- 对 Request、Response 的扩展 -->
<filter>
    <filter-name>InitMvcRequest</filter-name>
    <filter-class>com.ajaxjs.web.InitMvcRequest</filter-class>
</filter>
<filter-mapping>
    <filter-name>InitMvcRequest</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Boot 下使用:继承 InitMvcRequest 并声明为组件即可。

@Component
@Order(1)
InitMvcRequestFilter extends InitMvcRequest {
}

如果不自动扫描包,那么加入下面 bean:

<!--对 Request、Response 的扩展-->
<bean class="com.ajaxjs.web.InitMvcRequest" />

Spring 工具类

就地取材,Spring 本身包含不少优秀的工具类,既然 Spring 为底层必定依赖的库,那么请大胆使用其工具栏吧~我知道的是,有些团队约束(或禁止)成员去写自己的工具类,例如 StringUtil.isEmpty() 之类的。

// 最常用的,判断是否空字符串
StringUtils.hasText();
// 将第一个字符改大写
StringUtils.capitalize(Str);

ObjectUtils.isEmpty([]);
CollectionUtils.isEmpty(List/Map);

Base64Utils.encodeToString();
Base64Utils.decodeFromString();

StreamUtils.copyToByteArray();

UriUtils.encode(v.toString(), "utf-8");

/**
 * 将字符进行 URL 编码,默认 UTF-8 编码
 * 
 * jdk自带的URL编码工具类 URLEncoder 在对字符串进行URI编码的时候,会把空格编码为 + 号。
 * 空格的URI编码其实是:%20 搜素引擎上不少人都遇到这个问题,哀声一片。
 * 解决办法大都是对编码后的字符串,进行 + 号替换为 %20。总感觉这种方式不优雅
 * 
 * @param str 正常的 Java 字符串
 * 
 * @return 已 URL 编码的字符串
 */
public static String urlEncode(String str) {
	try {
		return URLEncoder.encode(str, StandardCharsets.UTF_8.toString());
	} catch (UnsupportedEncodingException e) {
		LOGGER.warning(e);
		return null;
	}
}

/**
 * 将 URL 编码的字符还原,默认 UTF-8 编码
 * 
 * @param str 已 URL 编码的字符串
 * @return 正常的 Java 字符串
 */
public static String urlDecode(String str) {
	try {
		return URLDecoder.decode(str, StandardCharsets.UTF_8.toString());
	} catch (UnsupportedEncodingException e) {
		LOGGER.warning(e);
		return null;
	}
}

以前写的

/**
 * 将一个字符串分隔为字符串数组,分隔符 可以是,、/、-、\(注意转义)、|、; 作为分隔符。 常在读取配置的时候使用。
 * 
 * @param str 输入的字符串
 * @return 分隔后的数组
 */
public static String[] split(String str) {
	return str.split(",|/|-|\\\\|\\||;");
}

@Test
public void testSplit() {
	assertEquals(2, split("a,b").length);
	assertEquals(3, split("a/b/c").length);
	assertEquals(4, split("a\\b\\c\\d").length);
	assertEquals(5, split("a|b|c|d|e").length);
	assertEquals(5, split("a;b;c;d;e").length);
}

/**
 * 重复字符串 repeat 次并以 div 分隔
 * 
 * @param str    要重复的字符串
 * @param div    字符串之间的分隔符
 * @param repeat 重复次数
 * @return 结果
 */
public static String repeatStr(String str, String div, int repeat) {
	StringBuilder s = new StringBuilder();
	int i = 0;

	while (i++ < repeat) {
		s.append(str);
		if (i != repeat)
			s.append(div);
	}

	return s.toString();
}

@Test
public void testRepeatStr() {
	assertEquals(repeatStr("Hi", ",", 3), "Hi,Hi,Hi");
}

/**
 * 输入 a,看 a 里面是否包含另一个字符串 b,忽略大小写。
 * 
 * @param a 输入字符串 a
 * @param b 另一个字符串 b
 * @return true 表示包含
 */
public static boolean containsIgnoreCase(String a, String b) {
	return a.toLowerCase().contains(b.toLowerCase());
}

@Test
public void testContainsIgnoreCase() {
	assertTrue(containsIgnoreCase("abc", "A"));
}

/**
 * 随机字符串
 */
private static final String STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

/**
 * 生成指定长度的随机字符,可能包含数字
 * 
 * @param length 户要求产生字符串的长度
 * @return 随机字符
 */
public static String getRandomString(int length) {
	Random random = new Random();
	StringBuffer sb = new StringBuffer();

	for (int i = 0; i < length; i++) {
		int number = random.nextInt(62);
		sb.append(STR.charAt(number));
	}

	return sb.toString();
}

/**
 * 是否空字符串
 * 
 * @param str 要判断的字符串
 * @return true 表示为为空字符串,否则不为空
 */
public static boolean isEmptyString(String str) {
	return str == null || str.isEmpty() || str.trim().isEmpty();
}
/**
 * 将第一个字母大写
 * 
 * @param str 字符串
 * @return 字符串
 */
public static String firstLetterUpper(String str) {
	// return str.substring(0, 1).toUpperCase() + str.substring(1); // 另外一种写法
	return Character.toString(str.charAt(0)).toUpperCase() + str.substring(1);
}
/**
 * 判断数组是否为空
 * 
 * @param arr 输入的数组
 * @return true 表示为素组不是为空,是有内容的,false 表示为数组为空数组,length = 0
 */
public static boolean isNull(Object[] arr) {
	return arr == null || arr.length == 0;
}

assertTrue(isNull(new Object[] {}));
assertFalse(isNull(new Object[] { null }));

/**
 * 判断 collection 是否为空
 * 
 * @param collection Map输入的集合
 * @return true 表示为集合不是为空,是有内容的,false 表示为空集合
 */
public static boolean isNull(Collection<?> collection) {
	return collection == null || collection.isEmpty();
}

/**
 * 判断 map 是否有意义
 * 
 * @param map 输入的
 * @return true 表示为 map 不是为空,是有内容的,false 表示为空 map
 */
public static boolean isNull(Map<?, ?> map) {
	return map == null || map.isEmpty();
}

@Test
public void testCollection() {
	assertTrue(isNull(new HashMap<String, String>() {
		private static final long serialVersionUID = 1L;
	}));
	assertTrue(isNull(new ArrayList<String>() {
		private static final long serialVersionUID = 1L;
	}));

	List<Object> list = null;
	assertTrue(isNull(list));
}


// ------------BASE 64
/**
 * BASE64 编码
 * 
 * @param bytes 输入的字节数组
 * @return 已编码的字符串
 */
public static String base64Encode(byte[] bytes) {
	return Base64.getEncoder().encodeToString(bytes);
}

/**
 * BASE64 编码
 * 
 * @param str 待编码的字符串
 * @return 已编码的字符串
 */
public static String base64Encode(String str) {
	return base64Encode(str.getBytes(StandardCharsets.UTF_8));
}

/**
 * BASE64 解码,但以 Byte 形式返回
 * 
 * @param str 待解码的字符串
 * @return 已解码的 Byte
 */
public static byte[] base64DecodeAsByte(String str) {
	try {
		return Base64.getDecoder().decode(str);
	} catch (IllegalArgumentException e) {
		LOGGER.warning("BASE64 解码失败", e);
		return null;
	}
}

/**
 * BASE64 解码 这里需要强制捕获异常。
 * 中文乱码:http://s.yanghao.org/program/viewdetail.php?i=54806
 * 
 * @param str 待解码的字符串
 * @return 已解码的字符串
 */
public static String base64Decode(String str) {
	byte[] b = base64DecodeAsByte(str);
	return b == null ? null : byte2String(b);
}

  Stream

/**
 * 使用内存操作流,读取二进制,也就是将流转换为内存的数据。 InputStream 转换到 byte[]. 从输入流中获取数据, 转换到 byte[]
 * 也就是 in 转到内存。虽然大家可能都在内存里面了但还不能直接使用,要转换
 * 
 * @param in 输入流
 * @return 返回本实例供链式调用
 */
public static byte[] inputStream2Byte(InputStream in) {
	// 使用内存操作流,读取二进制
	try (ByteArrayOutputStream out = new ByteArrayOutputStream();) {
		write(in, out, true);

		return out.toByteArray();
	} catch (IOException e) {
		LOGGER.warning(e);
		return null;
	}
}

标签:return,String,经验谈,Spring,static,str,使用,字符串,public
来源: https://blog.csdn.net/zhangxin09/article/details/118638907

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有