# try-with-resource结合http协议导致参数漏传

  • 代码复现
class Demo {
    
    public  void someFunction(){
      URL addressUrl = new URL(address);
      URLConnection conn = addressUrl.openConnection();

      try(OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
          BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));) 	{
        out.write("参数...");
        out.flush();
        //读取通信结果...略
      }
      
      //...省略...
    }
}

  • 问题说明

    http客户端打开输入流时,会触发发送请求。但是此时发送缓存区没有数据,因此发送了一个空请求!

# SimpleDateFormate调试正常,线上异常

  • 代码复现
class Test{
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    
    public static void Test1(){
        dateFormat.format(new Date());
    }
    
    public void Test2(){
        dateFormat.format(new Date());
    }
}
  • 问题说明
    • 报错: java.lang.NumberFormatException: multiple pints
    • SimpleDateFormat的format方法实际操作的就是Calendar**(Calendar变量也就是一个共享变量线程不安全)**,也正是因为每次在转化时间的时候foramat会先把时间set到calendar中,这样就会导致A线程读取到B线程的时间.

# spring+tomcat启动的项目,静态资源如js中文乱码,怎么设置编码都没用

  • 问题说明 jsp文件引入了多个 js,js中包含中文, 其中浏览器为utf8编码,静态资源为utf8编码,最后加载的静态资源依然乱码

  • 问题说明

    • defaultServlet默认会处理静态资源,在没有使用全局的springMvc代理之前,所有的静态资源将由defaultServlet处理,而该servlet的默认编码为iso-8859-1编码
    • 简言之,应用层面的编码配置,有其作用范围,对于defaultServlet,需要去设置tomcat本身的配置,本质上而言,这是框架问题,因为其与环境耦合了

# springBoot项目,宽松配置失效

# 问题说明

  • 以某框架为例, 配置了多个配置项(本意是为了更好的兼容), 有如下注解:
@Configuration
@ConditionalOnProperty(
    prefix = "xxx.database.mybatis",
    name = {"datasourceList", "datasource-list"}
)
public class MybatisConfig {}
  • 但是实际页面中,只配置了其中的一项
  • 常规启动下没有问题,但是引入了依赖的情况下,遇到了两次配置触发条件不生效的问题;
  • 经最终排查,发现是由于springCloud+springBoot版本不兼容导致的,或者说其本来就有这个bug

# 问题追踪记录

条件属性获取过程 条件属性判定过程说明 正常条件说明 异常条件说明 宽松对比方案说明1 宽松对比方案说明2

# 问题原因本质

原理说明1 原理说明2 原理说明3 原理说明4 原理说明5 原理说明6

# 解决方案

  • 方案一注意,由于类的可见性为包层级, 因此需在具体的包层级下定义扩展
package org.springframework.boot.context.properties.source;

import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource;
import org.springframework.boot.context.properties.source.SpringConfigurationPropertySources;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author automannn
 * @Date 2025/6/14
 */
public class SpringBootCloudAdaptApplicationListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {

    private static final String CUSTOM_ATTACHED_PROPERTY_SOURCE_NAME = "customConfigurationProperties";
    @Override
    public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
        ConfigurableEnvironment environment = event.getEnvironment();
        MutablePropertySources sources = environment.getPropertySources();

        Iterator iter = sources.iterator();

        List orinSources = new ArrayList();

        while(iter.hasNext()) {
            PropertySource<?> propertySource = (PropertySource)iter.next();
            if(! (propertySource instanceof ConfigurationPropertySourcesPropertySource)){
                orinSources.add(propertySource);
            }
        }

        environment.getPropertySources().addFirst(new ConfigurationPropertySourcesPropertySource(CUSTOM_ATTACHED_PROPERTY_SOURCE_NAME,
                    new SpringConfigurationPropertySources(orinSources)));

    }

}

class Main{
    public static void main(String[] args) {
      SpringApplication application = new SpringApplicationBuilder()
              .sources(Main.class)
              .listeners(new SpringBootCloudAdaptApplicationListener())
              .build(args);
    }
}
  
  • 方案二,由于该问题是StandardEncryptableEnvironment导致的,因此可以根据需要如无必要可不使用该类
解决方案1