hatenob

プログラムって分からないことだらけ

簡単なHTTPクライアント

今更作る必要ないものではあるけれど、ちょっとしたテストをしたかったので作りました。
簡単なRequestとResponse用のクラスを作った、という感じです。

public class HelloServletIT {
    private class HttpRequest {
        private String url;
        private String params;

        public HttpRequest(String url) {
            this.url = url;
        }

        public void setParams(String params) {
            this.params = params;
        }

        public String getRequestUrl() {
            if (params == null || "".equals(params)) {
                return url;
            }

            return url + "?" + params;
        }
    }

    private class HttpResponse {
        private int statusCode;
        private String contents;

        public HttpResponse(int statusCode, String contents) {
            this.statusCode = statusCode;
            this.contents = contents;
        }

        public int getStatusCode() {
            return statusCode;
        }

        public String getContents() {
            return contents;
        }
    }

    private String urlEncode(String param) {
        try {
            return URLEncoder.encode(param, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "";
        }
    }

    private <T> String marshalParam(T form, PropertyDescriptor pd) {
        if (pd.getReadMethod() == null || "class".equals(pd.getName())) {
            return "";
        }

        try {
            return pd.getName() + "="
                    + urlEncode(pd.getReadMethod().invoke(form).toString());
        } catch (IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e) {
            e.printStackTrace();
        }

        return "";
    }

    private <T> String marshalParams(T form) {
        List<String> params = new ArrayList<>();

        try {
            for (PropertyDescriptor pd : Introspector.getBeanInfo(
                    form.getClass()).getPropertyDescriptors()) {
                String marshalizedParam = marshalParam(form, pd);
                if (!"".equals(marshalizedParam)) {
                    params.add(marshalizedParam);
                }
            }
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }

        if (params.size() == 0) {
            return "";
        }

        return String.join("&", params);
    }

    private HttpResponse get(HttpRequest req) throws Exception {

        URL servletUrl = new URL(req.getRequestUrl());
        HttpURLConnection con = (HttpURLConnection) servletUrl.openConnection();

        int statusCode = con.getResponseCode();

        StringBuilder contents = new StringBuilder();
        try (BufferedReader br = new BufferedReader(new InputStreamReader(
                con.getInputStream()))) {
            br.lines().forEach(l -> contents.append(l));
        }

        return new HttpResponse(statusCode, contents.toString());
    }

    private static final String SERVLET_URL = "http://localhost:8080/s/servlet/hello";

    @Test
    public void test_hello() throws Exception {
        HttpRequest req = new HttpRequest(SERVLET_URL);

        HelloForm form = new HelloForm();
        form.setPrefix("Hey");
        form.setWord("abstract servlet");
        form.setPostfix("testing");
        req.setParams(marshalParams(form));

        HttpResponse res = get(req);

        assertThat(res.getStatusCode(), is(200));
        assertThat(res.getContents(), is("Hey hello abstract servlet testing"));
    }
}

応答を全部文字列にってのが何とも、、という感じ。
HTML返されたら検証が大変というか、無理かも。