spring boot rest控制器:如何返回干净的json

gwbalxhn  于 2021-07-16  发布在  Java
关注(0)|答案(2)|浏览(405)

我已将此方法设置为从spring boot rest控制器返回响应:

public ResponseEntity<Map<String, Object>> get(@PathVariable("id") long id) {
    try {
        return new ResponseEntity<>(this.ReportDAO.read("dbuser1"), HttpStatus.OK);
    } catch (Exception e) {
        return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

这就是道的方法:

@Autowired
private JdbcTemplate jdbcTemplate;
public Map<String, Object> read(String testParam) {
    List<SqlParameter> parameters = Arrays.asList(new SqlParameter(Types.NVARCHAR));
    CallableStatementCreator csc = new CallableStatementCreator() {
        @Override
        public CallableStatement createCallableStatement(Connection con) throws SQLException {
            CallableStatement cs = con.prepareCall("{call test (?)}");
            cs.setString(1, testParam);
            return cs;
        }
    };

    return jdbcTemplate.call(csc, parameters);
}

我成功地将一个json对象作为响应,但格式如下:


# result-set-1: [ {…}, {…} ]

当我期待有:

[ {…}, {…} ]

为什么要将结果集插入 #result-set-1 钥匙?我怎样才能改变这种行为?

t8e9dugd

t8e9dugd1#

JdbcTemplate#call 返回map<string,object>您可以通过使用key从map中提取key来改变此行为 #result-set-1 .
我就是这样做的:
sql语句

CREATE TABLE `sample_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `message` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

插入语句:

insert into sample_log (message) values('West Country');
insert into sample_log (message) values('Welcome User');

存储过程:

CREATE PROCEDURE  `fetch_sample_logs`(
    in message_query  varchar(30)
)
BEGIN
    SELECT * FROM new_db.sample_log where message like message_query;
END

控制器

@RequestMapping("/logs")
@RestController
class SampleLogController {
    private final JdbcTemplate jdbcTemplate;

    @Autowired
    SampleLogController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @GetMapping("/call")
    public Object get() {
        final Map<String, Object> call = jdbcTemplate.call(connection -> {
            CallableStatement cs = connection.prepareCall("{call fetch_sample_logs (?)}");
            cs.setString(1, "%wel%");
            return cs;
        }, Collections.singletonList(new SqlParameter(Types.VARCHAR)));
        return Optional.of(call.getOrDefault("#result-set-1", Collections.emptyList()));
    }
}
p1tboqfb

p1tboqfb2#

我建议您提取所有结果集并将它们合并在一起。您可以按照另一个答案的建议去做,只需从Map中获取“#result-set-1”,但我建议在从dao方法返回之前,至少将resultset转换为应用程序表示的对象(“thing”pojo)。我认为将结果集结合在一起可能是一个更持久的解决方案,除非有人能想出一个为什么不这样做的理由。

@Autowired
private JdbcTemplate jdbcTemplate;
public List<Thing> read(String testParam) {
    List<SqlParameter> parameters = Arrays.asList(new SqlParameter(Types.NVARCHAR));
    CallableStatementCreator csc = new CallableStatementCreator() {
        @Override
        public CallableStatement createCallableStatement(Connection con) throws SQLException {
            CallableStatement cs = con.prepareCall("{call test (?)}");
            cs.setString(1, testParam);
            return cs;
        }
    };
    Map<String, Object> result = jdbcTemplate.call(csc, parameters);

    return result.values().stream().map(o -> fromResultSet((ResultSet) o)
           .flatMap(List::stream).collect(toList());

}

private List<Thing> fromResultSet(ResultSet resultSet) {
    List<Thing> list = new ArrayList<>();
    while (resultSet.next()) {
      Thing thing = new Thing(resultSet.getString("resultCol1"), resultSet.getString("resultCol2")
      list.add(user);
    }
}

我将resultset中的一些代码修改为list,以实际解析结果集。

相关问题