使用 Apache ResponseHandler 处理 Http 返回信息

本文内容大多基于官方文档和网上前辈经验总结,经过个人实践加以整理积累,仅供参考。


Apache HttpClient 实现 Java 调用 Http 接口 中对 Http Response 的处理都是通过 org.apache.http.util.EntityUtilstoString 方法获取 Http 返回的文本信息,在之前提过官方文档中建议严格控制使用 EntityUtils 读取 HttpEntity 的信息

可以使用 org.apache.http.client.ResponseHandler 替代 EntityUtils 处理 Http Response

1 新建 CustomResponse 类作为所有 Http 接口的返回信息

public class CustomResponse {

    public static final int OK = 100;
    public static final int ERROR = 999;

    public CustomResponse() {}

    public CustomResponse(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    private int code;

    private String msg;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

}

2 修改 LoginService 的返回信息,由一个普通的字符串变为 CustomResponse 类实例的 JSON 字符串

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;

import util.CustomResponse;

public class LoginService extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        OutputStream outputStream = response.getOutputStream();
        response.setHeader("content-type", "application/json;charset=UTF-8");
        CustomResponse result = null;
        if (username == null) {
            result = new CustomResponse(CustomResponse.ERROR, "Post:请输入用户名!");
        } else if (password == null) {
            result = new CustomResponse(CustomResponse.ERROR, "Post:请输入密码!");
        } else if (!username.equals("unique")) {
            result = new CustomResponse(CustomResponse.ERROR, "Post:用户名错误!");
        } else if (!password.equals("ASDF")) {
            result = new CustomResponse(CustomResponse.ERROR, "Post:密码错误!");
        } else {
            result = new CustomResponse(CustomResponse.ERROR, "Post:验证通过~~");
        }
        outputStream.write(new Gson().toJson(result).getBytes("UTF-8"));
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        OutputStream outputStream = response.getOutputStream();
        response.setHeader("content-type", "application/json;charset=UTF-8");
        CustomResponse result = null;
        if (username == null) {
            result = new CustomResponse(CustomResponse.ERROR, "Get:请输入用户名!");
        } else if (password == null) {
            result = new CustomResponse(CustomResponse.ERROR, "Get:请输入密码!");
        } else if (!username.equals("unique")) {
            result = new CustomResponse(CustomResponse.ERROR, "Get:用户名错误!");
        } else if (!password.equals("ASDF")) {
            result = new CustomResponse(CustomResponse.ERROR, "Get:密码错误!");
        } else {
            result = new CustomResponse(CustomResponse.ERROR, "Get:验证通过~~");
        }
        outputStream.write(new Gson().toJson(result).getBytes("UTF-8"));
    }

}

3 修改 public static final String invokeHttpGet(String uri) 方法逻辑

修改前

public static final String invokeHttpGet(String uri) 
    throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    CloseableHttpResponse response = null;
    HttpGet httpGet = new HttpGet(uri);
    try {
        response = client.execute(httpGet);
        HttpEntity entity = response.getEntity();
        return EntityUtils.toString(entity);
    } finally {
        release(client, response);
    }
}

修改后

public static final CustomResponse invokeHttpGetS(String uri) 
    throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet(uri);
    ResponseHandler<CustomResponse> responseHandler = new ResponseHandler<CustomResponse>() {
        @Override
        public CustomResponse handleResponse(HttpResponse response) 
            throws ClientProtocolException, IOException {
            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() >= 300) {
                throw new HttpResponseException(
                    statusLine.getStatusCode(), 
                    statusLine.getReasonPhrase());
            }
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                throw new ClientProtocolException("Response contains no content!");
            }
            ContentType contentType = ContentType.getOrDefault(entity);
            Charset charset = contentType.getCharset();
            Reader reader = new InputStreamReader(entity.getContent(), charset);
            Gson gson = new GsonBuilder().serializeNulls().create();
            return gson.fromJson(reader, CustomResponse.class);
        }
    };
    return client.execute(httpGet, responseHandler);
}

从以上代码中还可以看出,使用 ResponseHandlerhandleResponse 方法无需管理连接,无论执行成功或出现异常,HttpClient 都会自动处理并保证释放连接。

4 单元测试

@Test
public void test() throws ClientProtocolException, IOException {
    String uri1 = "http://localhost:8080/Service/login";
    String uri2 = "http://localhost:8080/Service/login?username=unique";
    String uri3 = "http://localhost:8080/Service/login?password=ASDF";
    String uri4 = "http://localhost:8080/Service/login?username=unique1&password=ASDF";
    String uri5 = "http://localhost:8080/Service/login?username=unique&password=ASDF2";
    String uri6 = "http://localhost:8080/Service/login?username=unique&password=ASDF";

    assertEquals("Get:请输入用户名!", 
        HttpClientTool.invokeHttpGetS(uri1).getMsg());
    assertEquals("Get:请输入密码!", 
        HttpClientTool.invokeHttpGetS(uri2).getMsg());
    assertEquals("Get:请输入用户名!", 
        HttpClientTool.invokeHttpGetS(uri3).getMsg());
    assertEquals("Get:用户名错误!", 
        HttpClientTool.invokeHttpGetS(uri4).getMsg());
    assertEquals("Get:密码错误!", 
        HttpClientTool.invokeHttpGetS(uri5).getMsg());
    assertEquals("Get:验证通过~~", 
        HttpClientTool.invokeHttpGetS(uri6).getMsg());
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又言又语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值