Java获取HTTP下载文件文件名称

0

注意中间有段去符号的代码,这段代码只适合Java11默认HttpClient使用

	/**
	 * <p>获取文件名称</p>
	 * <p>下载文件名称:如果不存在返回默认的文件名称</p>
	 * <p>Content-Disposition:attachment;filename=snail.jar?version=1.0.0</p>
	 * <p>Content-Disposition:attachment;filename="snail.jar"</p>
	 * 
	 * @param defaultName 默认文件名称
	 */
	public String fileName(final String defaultName) {
		String fileName = header(CONTENT_DISPOSITION);
		if(StringUtils.isEmpty(fileName)) {
			return defaultName;
		}
		final String fileNameLower = fileName.toLowerCase();
		if(fileNameLower.contains(FILENAME)) { // 包含文件名称
			fileName = UrlUtils.decode(fileName); // URL解码
			int index = fileName.indexOf("=");
			if(index != -1) {
				// 截取名称
				fileName = fileName.substring(index + 1);
				// 去掉引号
				if(fileName.startsWith("\"") && fileName.endsWith("\"")) {
					fileName = fileName.substring(1, fileName.length() - 1);
				}
				// 去掉参数
				index = fileName.indexOf("?");
				if(index != -1) {
					fileName = fileName.substring(0, index);
				}
			}
			fileName = fileName.trim();
			if(StringUtils.isEmpty(fileName)) {
				return defaultName;
			}
			final var encoder = Charset.forName(SystemConfig.CHARSET_GBK).newEncoder();
			// 只是进行URL编码
			if(encoder.canEncode(fileName)) {
				return fileName;
			}
			// HttpClient工具汉字ISO-8859-1字符转为char没有去掉符号(& 0xFF)
			final char[] chars = fileName.toCharArray();
			for (int i = 0; i < chars.length; i++) {
				// 去掉符号
				chars[i] = (char) (chars[i] & 0x00FF);
			}
			fileName = new String(chars);
			// 处理ISO-8859-1编码
			// GBK
			final String fileNameGBK = StringUtils.charset(fileName, SystemConfig.CHARSET_ISO_8859_1, SystemConfig.CHARSET_GBK);
			// UTF-8
			final String fileNameUTF8 = StringUtils.charset(fileName, SystemConfig.CHARSET_ISO_8859_1);
			/*
			 * <p>判断依据</p>
			 * <p>GBK转为UTF8基本乱码</p>
			 * <p>UTF8转为GBK也会乱码,可能只是不是原来的字符,但是可以也是属于GBK字符。</p>
			 */
			if(encoder.canEncode(fileNameUTF8)) {
				return fileNameUTF8;
			}
			if(encoder.canEncode(fileNameGBK)) {
				return fileNameGBK;
			}
			// 其他编码直接返回
			return fileName;
		} else {
			return defaultName;
		}
	}