本文目录导读:

在Java中统一参数拼接流程,主要针对HTTP请求参数、SQL查询参数、日志拼接以及字符串模板等场景,不同场景有不同的最佳实践,但核心思想是避免手动拼接、防止注入、提高可读性。
以下是各场景下的统一流程方案:
HTTP 请求参数拼接(最常用)
场景:构建 GET 请求的 URL 查询参数(如GET /api?name=张三&age=25)。
推荐方案:使用 Spring 的 UriComponentsBuilder 或 HttpClient 的 URLEncodedUtils。
方案 A:Spring UriComponentsBuilder(最推荐)
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.Map;
public class HttpParamBuilder {
public static URI buildGetUrl(String baseUrl, Map<String, String> params) {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl);
params.forEach(builder::queryParam);
return builder.build().encode().toUri();
}
// 示例
public static void main(String[] args) {
Map<String, String> params = Map.of(
"name", "张三",
"age", "25",
"city", "北京"
);
URI uri = buildGetUrl("http://api.example.com/user", params);
System.out.println(uri);
// 输出: http://api.example.com/user?name=%E5%BC%A0%E4%B8%89&age=25&city=%E5%8C%97%E4%BA%AC
}
}
方案 B:Apache HttpClient 的 URLEncodedUtils
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class HttpParamBuilder {
public static String buildQueryString(List<NameValuePair> params) {
return URLEncodedUtils.format(params, StandardCharsets.UTF_8);
}
// 示例
public static void main(String[] args) {
List<NameValuePair> params = List.of(
new BasicNameValuePair("name", "张三"),
new BasicNameValuePair("age", "25")
);
String query = buildQueryString(params);
System.out.println(query);
// 输出: name=%E5%BC%A0%E4%B8%89&age=25
}
}
方案 C:手写通用工具(不依赖框架,但需处理编码)
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.stream.Collectors;
public class HttpParamBuilder {
public static String buildQueryString(Map<String, String> params) {
return params.entrySet().stream()
.map(entry -> encode(entry.getKey()) + "=" + encode(entry.getValue()))
.collect(Collectors.joining("&"));
}
private static String encode(String value) {
return URLEncoder.encode(value, StandardCharsets.UTF_8);
}
// 示例
public static void main(String[] args) {
Map<String, String> params = Map.of("name", "张三", "age", "25");
String query = buildQueryString(params);
System.out.println(query);
// 输出: name=%E5%BC%A0%E4%B8%89&age=25
}
}
SQL 参数拼接(防止 SQL 注入)
核心原则:永远不要手动拼接 SQL 字符串,必须使用 PreparedStatement / 参数化查询。
方案 A:JDBC PreparedStatement
String sql = "SELECT * FROM users WHERE name = ? AND age > ?";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setString(1, "张三");
ps.setInt(2, 18);
ResultSet rs = ps.executeQuery();
}
方案 B:MyBatis Plus QueryWrapper(最推荐)
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
.gt("age", 18);
List<User> users = userMapper.selectList(wrapper);
方案 C:JPA CriteriaQuery(类型安全)
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> root = query.from(User.class);
query.where(
cb.equal(root.get("name"), "张三"),
cb.gt(root.get("age"), 18)
);
List<User> users = entityManager.createQuery(query).getResultList();
日志参数拼接(提高性能 & 可读性)
核心原则:使用 SLF4J 的占位符 ,避免字符串拼接(特别是 操作)。
推荐方案(SLF4J + Logback)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserService {
private static final Logger log = LoggerFactory.getLogger(UserService.class);
public void createUser(String name, int age) {
// ✅ 正确:使用占位符,延迟求值
log.info("创建用户: name={}, age={}", name, age);
// ❌ 错误:字符串拼接 +,即使日志级别不输出也会执行
// log.info("创建用户: name=" + name + ", age=" + age);
}
}
进阶 - 避免参数对象 toString() 调用(使用 lambda):
log.debug("用户详情: {}", () -> user.toExpensiveString());
字符串模板拼接(通用场景)
方案 A:Java 15+ Text Blocks + String.format()
String name = "张三";
int age = 25;
String msg = String.format("姓名: %s, 年龄: %d", name, age);
方案 B:MessageFormat(国际化场景)
import java.text.MessageFormat;
String pattern = "用户 {0} 的年龄是 {1}";
String msg = MessageFormat.format(pattern, "张三", 25);
方案 C:Apache Commons Lang3 StringSubstitutor(模板替换)
import org.apache.commons.text.StringSubstitutor;
import java.util.Map;
Map<String, Object> params = Map.of("name", "张三", "age", 25);
String template = "用户 ${name} 的年龄是 ${age}";
String result = StringSubstitutor.replace(template, params);
// 输出: 用户 张三 的年龄是 25
统一流程的黄金法则
| 场景 | 推荐方式 | 核心原因 |
|---|---|---|
| HTTP GET参数 | UriComponentsBuilder / URLEncodedUtils |
自动编码,防止非法字符 |
| HTTP POST参数 | MultiValueMap + HttpEntity |
类型安全,支持多值 |
| SQL查询 | PreparedStatement / ORM框架 |
防SQL注入 |
| 日志 | SLF4J占位符 | 延迟求值,避免无谓性能损耗 |
| 通用字符串拼接 | String.format() / MessageFormat |
可读性强,支持国际化 |
| 复杂模板 | StringSubstitutor / Thymeleaf |
支持变量替换、条件逻辑 |
最终建议:
- 在项目中定义统一的
ParamUtils工具类(或使用现有类库如Spring、Apache Commons)。 - 禁止在代码中出现
"a=" + a + "&b=" + b这种手写拼接(尤其在HTTP和SQL场景)。 - 对团队进行代码审查,确保参数拼接流程统一、安全。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播