解析JSON数据
Servlet解析JSON数据
第一步 请求方法及请求数据
根据不同的请求方法重写不同的 doXXX 方法,请求方法大概有两种——doGet(),doPost(),当然也可以采用一步到位的方法,这样无论前端请求的是什么方法,都能够执行,增加了代码的复用性.
在 doPost() 方法中,设置请求数据和响应数据的编码类型以及响应数据类型
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");//请求编码类型
resp.setCharacterEncoding("UTF-8");//响应编码类型
resp.setContentType("application/json");//响应数据类型
}
第二步 解析请求数据
创建一个响应数据对象
JSONResponse json = new JSONResponse();
根据传进来的数据进行解析——对其进行反序列化,将传进来的 JSON 字符串反序列化为对应的对象(根据功能不同可能是 user, 也可能是其他),这样在执行业务的时候就可以使用对象执行
getInputStream()——获取到 JSON 字符串, User.class 参数是将 JSON 字符串转化成的内容
User user = JSONUtil.deserialize(
req.getInputStream(), User.class);
第三步 执行业务
业务就是前端需要服务器的什么内容,我们通过一系列的操作完成称作执行业务,在目前学习中,执行业务主要是对数据库进行增删改查的操作,如果业务操作成功则返回 true,如失败则返回错误码或者错误信息
User query = UserDAO.query(user);
json.setSuccess(true);//成功
//失败返回错误码及错误信息
json.setCode("ERROR");
json.setMessage("系统出错,请与管理员联系!");
第四步 返回响应数据
之前的操作都是对一个对象进行操作,而返回的响应数据需要的却是 JSON 数据,也就是说在返回响应数据之前要把对象转变成一个 JSON 字符串才行,把这个操作称为序列化
ObjectMapper m = new ObjectMapper();
String s = m.writeValueAsString(json);
为了方便,我们通常把反序列化和序列化方法写在同一个类中——JSONUtil
package org.example.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.InputStream;
public class JSONUtil {
private static ObjectMapper M = new ObjectMapper();
/**
* 序列化java对象为json字符串
*/
public static String serialize(Object o) throws JsonProcessingException {
return M.writeValueAsString(o);
}
/**
* 反序列化输入流中的json字符串为java对象
*/
public static <T> T deserialize(InputStream is,
Class<T> c) throws IOException {
return M.readValue(is, c);
}
}
最后使用 PrintWriter 中的 getWriter() 方法返回,但通常连起来写
PrintWriter p = resp.getWriter();
p.println(s);
-------------------------------------------------------------
resp.getWriter().println(s)
到此,一个 Httpservlet 的 JSON 数据请求响应就完成了
Servler 的数据库操作——JDBC
连接数据库
MysqlDataSource ds = new MysqlDataSource();//获取数据库的基本内容
ds.setURL("jdbc:mysql://localhost:3306/servlet_blog");//URL:jdbc:mysql://服务器地址:端口号/数据库名
ds.setCharacterEncoding("UTF-8");//编码类型
ds.setUser("root");//用户名
ds.setPassword("2222");//密码
ds.setUseSSL(false);//SSL 加密: true;不加密: false
Connection c = ds.getConnection();//连接数据库
PreparedStatment——执行 SQL 语句
SQL 在 Java 中是一个字符串,想让其能够操作到数据库就需要 PerparedStatement 与数据库进行连接并执行
主要掌握两种执行SQL的方法:executeQuery() 方法执行后返回单个结果集的,通常用于select语句
executeUpdate()方法返回值是一个整数,指示受影响的行数,通常用于update、insert、delete语句
增
Connection c = null;
PreparedStatement pw = null;
try{
c = DBUtil.getConnection();
String sql = "insert into article(title, content, user_id) " +
"values(?, ?, ?)" ;
pw = c.prepareStatement(sql);
//3、先替换占位符的值,再执行sql
pw.setString(1, a.getTitle());
pw.setString(2, a.getContent());
pw.setInt(3, id);
//4、执行sql语句
//插入,修改,删除都是调用executeUpdate的方法,返回值都是int
//表示影响了多少行的数据
return pw.executeUpdate();
删
Connection c = null;
PreparedStatement pw = null;
try{
c = DBUtil.getConnection();
//文章的title和content可以从Servlet中获取,使用Session中获取
StringBuilder sql = new StringBuilder("delete from article where id in(");
for(int i = 0; i < ids.length; i++){
if(i != 0){
sql.append(",");
}
sql.append("?");
}
sql.append(")");
pw = c.prepareStatement(sql.toString());
//3、先替换占位符的值,再执行sql
for(int i = 0; i < ids.length; i++){
pw.setInt(i + 1, Integer.parseInt(ids[i]));
}
//4、执行sql语句
return pw.executeUpdate();
改
Connection c = null;
PreparedStatement pw = null;
try{
c = DBUtil.getConnection();
//文章的title和content可以从Servlet中获取,使用Session中获取
String sql = "update article set title = ?, content = ? where id = ? ";
pw = c.prepareStatement(sql);
//3、先替换占位符的值,再执行sql
pw.setString(1, a.getTitle());
pw.setString(2, a.getContent());
pw.setInt(3, a.getId());
//4、执行sql语句
//插入,修改,删除都是调用executeUpdate的方法,返回值都是int
return pw.executeUpdate();
查
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
c = DBUtil.getConnection();
//书写 SQL 语句
String sql = "select id, nickname, sex, birthday," +
" head from user where username=? and password=?";
ps = c.prepareStatement(sql);
//替换占位符
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
//执行并处理结果集
rs = ps.executeQuery();
//executeQuery() 方法返回的是一个字符串,接下来要将这个字符串变成 对象集
User query = null;
while(rs.next()){//如果下一行还有数据,那么就是 true
query = new User();
query.setId(rs.getInt("id"));//rs.get("id") 是将结果集中的 id 一项打印出来给 query 的 setId
//因为 Username 和 Password 是作为参数传进来的,所以可以直接使用,当然也可以使用结果集获取
query.setUsername(user.getUsername());
query.setPassword(user.getPassword());
query.setNickname(rs.getString("nickname"));
query.setSex(rs.getBoolean("sex"));
Timestamp t = rs.getTimestamp("birthday");
if(t != null)
query.setBirthday(new Date(t.getTime()));
query.setHead(rs.getString("head"));
}
return query;
释放数据库资源
在对一个数据库执行完毕之后都要释放资源,在此为了方便观看,直接采用 类.close() 的形式释放资源
//释放结果集
ResultSet.close();
//释放 PreparedStatement
PreparedStatement.close();
//释放连接
Connection.close();
JDBC 总结executeUpdate
在不同的操作中 增、删、改 都差不多,只是在 SQL 的书写上不同,其余都相同,执行方法 executeUpdate() ——返回 int
而查找(select) 的执行方法是 executeQuery(),它的返回值是一个结果集,根据 servlet 所需要的类型进行处理,如果是对象的话就创建一个对象实例,然后使用对象的 set 方法对其进行修改
**注:**查找的时候使用 ResulSet.getInt(String) 的方法获取到结果集中对应的数据