查询路径变量时发生内部服务器错误 jdbc
Internal server error jdbc when querying a path variable
我有下面的代码,当 运行 我得到以下错误。 String
到 VARCHAR
的转换似乎存在某种问题。
curl -v localhost:8080/trainer/Rach
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /trainer/Rach HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 500
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Wed, 17 Jun 2020 12:43:21 GMT
< Connection: close
<
{"timestamp":"2020-06-17T12:43:21.205+0000","status":500,"error":"Internal Server Error","message":"StatementCallback; bad SQL grammar [SELECT * fr
om TRAINERS where NAME=Rach]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Column \"RACH\" not found; SQL statement:\nSELECT * from
TRAINERS where NAME=Rach [42122-200]","path":"/trainer/Rach"}* Closing connection 0
控制器:
@GetMapping("/trainer/{trainer_name}")
public Trainer getTrainer(@PathVariable String trainer_name) {
Trainer t = jdbcTemplate.queryForObject("SELECT * from TRAINERS where NAME=" + trainer_name , new
TrainerRawMapper());
return t;
}
原始映射器:
public class TrainerRawMapper implements RowMapper<Trainer> {
@Override
public Trainer mapRow(ResultSet rs, int rowNum) throws SQLException {
Trainer trainer = new Trainer();
trainer.setName(rs.getString("NAME"));
trainer.setLevel(rs.getInt("LEVEL"));
trainer.setBag(new Stack<Pokemon>());
return trainer;
}
}
Sql:
CREATE TABLE TRAINERS (NAME VARCHAR(225) PRIMARY KEY,
LEVEL INT)
-- TRAINERS insertions
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rach',8);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rache',0);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rachel',1);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Racheli',2);
更新查询并将 trainer_name
不带引号,如下所示:
String sql = "SELECT * from TRAINERS where NAME = '" + trainer_name +"'";
Trainer t = jdbcTemplate.queryForObject(sql, new TrainerRawMapper());
解决方案只是为了纠正错误。
, 出于安全原因 最好使用 jdbcTemplate 来替换值以避免 SQL 攻击,例如 SQL 注入
String sql = "SELECT * from TRAINERS where NAME = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{trainer_name}, new TrainerRawMapper());
主要问题是您正在使用 String concat 生成查询,这是非常危险的,在这种情况下会导致错误的查询。这些值未转义,因此查询无效。您应该做的是使用适当的 JDBC 机制来替换查询中的值。
String query = "SELECT * from TRAINERS where NAME=?"
return jdbcTemplate.queryForObject(query, new TrainerRawMapper(), trainer_name);
查询现在可以正确执行,您也可以免受 SQL 注入攻击。额外的好处是查询现在可以被缓存,从而在再次执行时提高性能。
我有下面的代码,当 运行 我得到以下错误。 String
到 VARCHAR
的转换似乎存在某种问题。
curl -v localhost:8080/trainer/Rach
* Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /trainer/Rach HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 500
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Wed, 17 Jun 2020 12:43:21 GMT
< Connection: close
<
{"timestamp":"2020-06-17T12:43:21.205+0000","status":500,"error":"Internal Server Error","message":"StatementCallback; bad SQL grammar [SELECT * fr
om TRAINERS where NAME=Rach]; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Column \"RACH\" not found; SQL statement:\nSELECT * from
TRAINERS where NAME=Rach [42122-200]","path":"/trainer/Rach"}* Closing connection 0
控制器:
@GetMapping("/trainer/{trainer_name}")
public Trainer getTrainer(@PathVariable String trainer_name) {
Trainer t = jdbcTemplate.queryForObject("SELECT * from TRAINERS where NAME=" + trainer_name , new
TrainerRawMapper());
return t;
}
原始映射器:
public class TrainerRawMapper implements RowMapper<Trainer> {
@Override
public Trainer mapRow(ResultSet rs, int rowNum) throws SQLException {
Trainer trainer = new Trainer();
trainer.setName(rs.getString("NAME"));
trainer.setLevel(rs.getInt("LEVEL"));
trainer.setBag(new Stack<Pokemon>());
return trainer;
}
}
Sql:
CREATE TABLE TRAINERS (NAME VARCHAR(225) PRIMARY KEY,
LEVEL INT)
-- TRAINERS insertions
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rach',8);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rache',0);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Rachel',1);
INSERT INTO TRAINERS (NAME,LEVEL) VALUES ('Racheli',2);
更新查询并将 trainer_name
不带引号,如下所示:
String sql = "SELECT * from TRAINERS where NAME = '" + trainer_name +"'";
Trainer t = jdbcTemplate.queryForObject(sql, new TrainerRawMapper());
解决方案只是为了纠正错误。
, 出于安全原因 最好使用 jdbcTemplate 来替换值以避免 SQL 攻击,例如 SQL 注入
String sql = "SELECT * from TRAINERS where NAME = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{trainer_name}, new TrainerRawMapper());
主要问题是您正在使用 String concat 生成查询,这是非常危险的,在这种情况下会导致错误的查询。这些值未转义,因此查询无效。您应该做的是使用适当的 JDBC 机制来替换查询中的值。
String query = "SELECT * from TRAINERS where NAME=?"
return jdbcTemplate.queryForObject(query, new TrainerRawMapper(), trainer_name);
查询现在可以正确执行,您也可以免受 SQL 注入攻击。额外的好处是查询现在可以被缓存,从而在再次执行时提高性能。