如何将Java结果集转换为JSON?

我有一个使用JDBC连接器的MySQL查询结果集。 所以我的工作是将结果集转换为JSON格式。 这样我就可以将它作为AJAX响应发送到客户端。 有些人可以解释如何转换为JSON格式,因为我不熟悉Java以及JSON的概念

很多人都正确回答了这个问题。 但是,我认为我可以使用以下一小段代码为post添加更多价值。 它使用Apache-DBUtilsGson库。

 public static String resultSetToJson(Connection connection, String query) { List> listOfMaps = null; try { QueryRunner queryRunner = new QueryRunner(); listOfMaps = queryRunner.query(connection, query, new MapListHandler()); } catch (SQLException se) { throw new RuntimeException("Couldn't query the database.", se); } finally { DbUtils.closeQuietly(connection); } return new Gson().toJson(listOfMaps); } 

如果您使用的是JSON,我推荐使用Jackson JSON库。

http://wiki.fasterxml.com/JacksonHome

jar文件可以在这里找到:

http://wiki.fasterxml.com/JacksonDownload

下面是我用来将任何结果集转换为Map <>或List

>的通用代码。使用JacksonJSON将其转换为JSON非常简单(见下文)。

 package com.naj.tmoi.entity; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class EntityFactory { public EntityFactory(Connection connection, String queryString) { this.queryString = queryString; this.connection = connection; } public Map findSingle(Object[] params) throws SQLException { List> objects = this.findMultiple(params); if (objects.size() != 1) { throw new SQLException("Query did not produce one object it produced: " + objects.size() + " objects."); } Map object = objects.get(0); //extract only the first item; return object; } public List> findMultiple(Object[] params) throws SQLException { ResultSet rs = null; PreparedStatement ps = null; try { ps = this.connection.prepareStatement(this.queryString); for (int i = 0; i < params.length; ++i) { ps.setObject(1, params[i]); } rs = ps.executeQuery(); return getEntitiesFromResultSet(rs); } catch (SQLException e) { throw (e); } finally { if (rs != null) { rs.close(); } if (ps != null) { ps.close(); } } } protected List> getEntitiesFromResultSet(ResultSet resultSet) throws SQLException { ArrayList> entities = new ArrayList<>(); while (resultSet.next()) { entities.add(getEntityFromResultSet(resultSet)); } return entities; } protected Map getEntityFromResultSet(ResultSet resultSet) throws SQLException { ResultSetMetaData metaData = resultSet.getMetaData(); int columnCount = metaData.getColumnCount(); Map resultsMap = new HashMap<>(); for (int i = 1; i <= columnCount; ++i) { String columnName = metaData.getColumnName(i).toLowerCase(); Object object = resultSet.getObject(i); resultsMap.put(columnName, object); } return resultsMap; } private final String queryString; protected Connection connection; } 

在servlet中,我使用com.fasterxml.jackson.databind.ObjectMapper将List转换为JSON,它将Javagenerics转换为JSON字符串。

  Connection connection = null; try { connection = DataSourceSingleton.getConnection(); EntityFactory nutrientEntityFactory = new EntityFactory(connection, NUTRIENT_QUERY_STRING); List> nutrients = nutrientEntityFactory.findMultiple(new Object[]{}); ObjectMapper mapper = new ObjectMapper(); String json = mapper.writeValueAsString(nutrients); response.setContentType("application/json;charset=UTF-8"); response.getWriter().write(json); } catch (SQLException e) { throw new ServletException(e); } finally { if (connection != null) { try { connection.close(); } catch (SQLException e) { throw new ServletException(e); } } } 

您可以将参数传递给PreparedStatement,如下所示:

 String name = request.getHeader("name"); EntityFactory entityFactory = new EntityFactory(DataSourceSingleton.getConnection(), QUERY_STRING); Map object = entityFactory.findSingle(new String[]{name}); private static final String QUERY_STRING = "SELECT NAME, PASSWORD, TOKEN, TOKEN_EXPIRATION FROM USER WHERE NAME = ?"; 

}

我使用了Google GSON库,它是mywebapp / WEB-INF / lib文件夹中的一个小型gson-2.2.4.jar 190KB库。 http://code.google.com/p/google-gson/

 import com.google.gson.stream.JsonWriter; --- httpres.setContentType("application/json; charset=UTF-8"); httpres.setCharacterEncoding("UTF-8"); JsonWriter writer = new JsonWriter(new OutputStreamWriter(httpres.getOutputStream(), "UTF-8")); while(rs.next()) { writer.beginObject(); // loop rs.getResultSetMetadata columns for(int idx=1; idx<=rsmd.getColumnCount(); idx++) { writer.name(rsmd.getColumnLabel(idx)); // write key:value pairs writer.value(rs.getString(idx)); } writer.endObject(); } writer.close(); httpres.getOutputStream().flush(); 

如果您想要键入的JSON键:值对,则有一个writer.value(String,long,integer等)setter。 在foreach rsmd循环中执行switch-case并对编号的sql类型使用适当的setter。 默认可以使用writer.value(rs.getString(idx))setter。

使用JsonWriter可以有效地编写大型json回复CPU + RAM。 您不需要首先循环sqlresultset并在RAM中创建大量List。 然后在编写json文档时再次循环列表。 这个例子一直流动,http回复被分块,而剩余的数据仍被写入servlet输出。

相对容易在GSON + Sql结果集周围创建更高级别的包装器。 jsp页面可以在编写http回复时使用SqlIterator(sqlquery)方法(.next(),getColumnCount(),getType(idx),. getString(idx),. getLong(idx)...)。 它循环原始的sql而没有中间List。 这对于较小的应用程序无关紧要,但重度使用的应用程序必须更密切地考虑cpu + ram使用模式。 或者甚至更好的做SqlToJson(httpresponse,sqlrs)帮助器然后jsp或servlet代码noice是最小的。

您可以使用任何JSON库。

以下是此实现,返回一个列表,每个元素都有一个JSON对象:

 /* * Convert ResultSet to a common JSON Object array * Result is like: [{"ID":"1","NAME":"Tom","AGE":"24"}, {"ID":"2","NAME":"Bob","AGE":"26"}, ...] */ public static List getFormattedResult(ResultSet rs) { List resList = new ArrayList(); try { // get column names ResultSetMetaData rsMeta = rs.getMetaData(); int columnCnt = rsMeta.getColumnCount(); List columnNames = new ArrayList(); for(int i=1;i<=columnCnt;i++) { columnNames.add(rsMeta.getColumnName(i).toUpperCase()); } while(rs.next()) { // convert each object to an human readable JSON object JSONObject obj = new JSONObject(); for(int i=1;i<=columnCnt;i++) { String key = columnNames.get(i - 1); String value = rs.getString(i); obj.put(key, value); } resList.add(obj); } } catch(Exception e) { e.printStackTrace(); } finally { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } return resList; } 
  • 将结果集转换为List> (每个映射包含一列,其中列名作为键,列内容作为值,List是此类行的列表)
  • 使用Gson或Jackson库将此对象转换为JSON。

如果你想使用Spring,这很容易:

 @RestController public class MyController @Autowired private JdbcTemplate jdbcTemplate; @RequestMapping("/") List> getAll() { return jdbcTemplate.queryForList("select * from my_table"); } } 

在mvc-dispatcher-servlet.xml中,您可以像这样设置JdbcTemplate:

   ...data source config...   

jackson应该在你的类路径中(即Maven依赖)。

使用jsonlib for Java。 迭代结果集并从jsonlib添加所需的属性作为JSONObject对象。

在我的应用程序中(浏览器上的MySQL / java servlet / javascript)我使用带有快速stringbuilder方法的字符串函数和通用的rs.getObject()。 我认为这是最优雅的工作方式:

 public String rStoJason(ResultSet rs) throws SQLException { if(rs.first() == false) {return "[]";} else {rs.beforeFirst();} // empty rs StringBuilder sb=new StringBuilder(); Object item; String value; java.sql.ResultSetMetaData rsmd = rs.getMetaData(); int numColumns = rsmd.getColumnCount(); sb.append("[{"); while (rs.next()) { for (int i = 1; i < numColumns + 1; i++) { String column_name = rsmd.getColumnName(i); item=rs.getObject(i); if (item !=null ) {value = item.toString(); value=value.replace('"', '\'');} else {value = "null";} sb.append("\"" + column_name+ "\":\"" + value +"\","); } //end For = end record sb.setCharAt(sb.length()-1, '}'); //replace last comma with curly bracket sb.append(",{"); } // end While = end resultset sb.delete(sb.length()-3, sb.length()); //delete last two chars sb.append("}]"); return sb.toString(); }