Внутренняя ошибка сервера jdb c при запросе переменной пути - PullRequest
1 голос
/ 17 июня 2020

У меня есть код ниже, и при запуске я получаю следующую ошибку. Кажется, есть какая-то проблема с преобразованием 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;
    }

RawMapper:

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);

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Основная проблема заключается в том, что вы используете String concat для создания запроса, это очень опасно и в этом случае приводит к неправильному запросу. Значения не экранированы и, следовательно, недопустимый запрос. Что вам нужно было сделать, так это использовать соответствующие механизмы JDB C для замены значений в вашем запросе.

String query = "SELECT * from TRAINERS where NAME=?"
return jdbcTemplate.queryForObject(query, new TrainerRawMapper(), trainer_name);

Запрос теперь будет выполняться правильно, и вы также защищены от SQL инъекционных атак. Дополнительное преимущество: запрос теперь может кэшироваться, что приводит к увеличению производительности при повторном выполнении.

0 голосов
/ 17 июня 2020

Обновите запрос и поместите 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());

Spring Do c :: queryForObject

...