面试题答案
一键面试常用验证方式
- 使用参数化查询(针对SQL注入)
- 在Java中,使用
PreparedStatement
代替Statement
。PreparedStatement
会预编译SQL语句,将参数与SQL语句分开处理,从而防止恶意用户通过输入特殊字符篡改SQL逻辑。 - 示例:
- 在Java中,使用
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SQLExample {
public static void main(String[] args) {
String username = "testUser";
String password = "testPassword";
String sql = "SELECT * FROM users WHERE username =? AND password =?";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "root");
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
System.out.println("User found");
} else {
System.out.println("User not found");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
- 正则表达式验证
- 可以用于验证输入是否符合特定的格式要求,比如邮箱、手机号等。这能防止用户输入不符合预期格式的数据,减少潜在风险。
- 示例:验证邮箱格式
import java.util.regex.Pattern;
public class EmailValidator {
private static final String EMAIL_PATTERN =
"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$";
public static boolean validateEmail(String email) {
return Pattern.matches(EMAIL_PATTERN, email);
}
}
- 白名单验证
- 确定允许输入的字符范围,只接受在白名单内的字符。比如在用户名验证中,只允许字母、数字和下划线。
- 示例:验证用户名
public class UsernameValidator {
public static boolean validateUsername(String username) {
return username.matches("^[a-zA-Z0-9_]+$");
}
}
- 长度限制
- 对输入的长度进行限制,避免用户输入过长的数据导致缓冲区溢出等问题。比如设置密码长度在8 - 16位之间。
- 示例:
public class PasswordValidator {
public static boolean validatePassword(String password) {
return password.length() >= 8 && password.length() <= 16;
}
}
- 使用安全的命令执行方式(针对命令注入)
- 在执行外部命令时,使用
ProcessBuilder
并对输入进行严格验证,避免用户输入恶意命令。 - 示例:执行系统命令获取文件列表
- 在执行外部命令时,使用
import java.io.IOException;
public class CommandExecutionExample {
public static void main(String[] args) {
String directory = "/home/user";
try {
ProcessBuilder processBuilder = new ProcessBuilder("ls", directory);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("Command executed successfully");
} else {
System.out.println("Command execution failed");
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
Java Web应用中表单输入验证示例(以Spring Boot为例)
- 引入依赖
在
pom.xml
中添加spring-boot-starter-validation
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 定义实体类并添加验证注解
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class UserForm {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度必须在3到20之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 8, max = 16, message = "密码长度必须在8到16之间")
private String password;
// getters and setters
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
- 在Controller中进行验证
import javax.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Validated
public class UserController {
@PostMapping("/register")
public ResponseEntity<String> register(@Valid @RequestBody UserForm userForm) {
return new ResponseEntity<>("注册成功", HttpStatus.OK);
}
}
这样,当用户提交表单数据时,Spring会自动根据定义的验证规则对输入进行验证,如果验证不通过,会返回相应的错误信息。