用纯Servlet实现一个REST“框架”,就这么简单!

mallon 发布于 2014/03/24 20:43
阅读 2K+
收藏 18
/**
 * REST请求分派器
 */
@WebServlet(name = "Dispatcher", urlPatterns = "/rest/*")
public class Dispatcher extends HttpServlet {
    /**
     * URL与请求处理器的映射
     */
    private Map<Pattern, Class> handlers = new HashMap<Pattern, Class>() {{
        put(Pattern.compile("^/devices/([^/]+)$"), DeviceHandler.class);
    }};

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            boolean matched = false;
            String path = request.getPathInfo();
            for (Pattern pattern : handlers.keySet()) {
                Matcher matcher = pattern.matcher(path);
                if (matcher.lookingAt()) {
                    int groupCount = matcher.groupCount();
                    String[] args = new String[groupCount];
                    if (groupCount > 0) {
                        for (int i = 0; i < matcher.groupCount(); i++) {
                            args[i] = matcher.group(i + 1);
                        }
                    }
                    Class handlerClass = handlers.get(pattern);
                    Object handlerInstance = handlerClass.newInstance();
                    handlerClass.getField("request").set(handlerInstance, request);
                    handlerClass.getField("response").set(handlerInstance, response);
                    handlerClass.getMethod(request.getMethod().toLowerCase(), String[].class).invoke(
                            handlerInstance,
                            (Object) args
                    );
                    matched = true;
                    break;
                }
            }
            if (!matched) {
                throw new Exception(String.format("No handler found to deal with path \"%s\"", path));
            }
        } catch (Exception ex) {
            response.setStatus(500);
            response.setContentType("text/plain;charset=UTF-8");
            PrintWriter out = response.getWriter();
            ex.printStackTrace(out);
            out.flush();
            out.close();
        }
    }
}


/**
 * REST请求处理器
 */
public abstract class Handler {
    public HttpServletRequest request;
    public HttpServletResponse response;

    public void get(String[] args) throws Exception {
        throw new Exception("Not implemented");
    }

    public void post(String[] args) throws Exception {
        throw new Exception("Not implemented");
    }

    public void put(String[] args) throws Exception {
        throw new Exception("Not implemented");
    }

    public void delete(String[] args) throws Exception {
        throw new Exception("Not implemented");
    }

    public void writeJsonObject(Object object) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.println(Json.dump(object));
        out.flush();
        out.close();
    }
}


/**
 *
 */
public class DeviceHandler extends Handler {
    @Override
    public void get(String[] args) throws Exception {
        Map ret = new HashMap();
        List result = Db.query("select id, name, description from devices");
        for (Object record : result) {
            Object id = ((Map) record).get("id");
            Map device;
            if (!ret.containsKey(id)) {
                device = new HashMap();
                ret.put(id, device);
            } else {
                device = (Map) ret.get(id);
            }
            device.put("name", ((Map) record).get("name"));
            device.put("description", ((Map) record).get("description"));
        }
        writeJsonObject(ret);
    }
}


加载中
0
景愿
景愿
LZ为何最近有如此雅兴调侃java?
0
凤城回忆
凤城回忆
Java强大吧
0
mallon
mallon

引用来自“雷锋叔叔”的答案

Java强大吧
@景愿 都说了,我其实是来黑Java的
凤城回忆
凤城回忆
想要批判它,就要深入的了解它。黑个痛快
0
jobell
jobell
HashMap 非线性安全,最好用ConcurrentHashMap
mallon
mallon
呵呵谢谢
0
투판시
투판시
楼主这么牛
0
小吱
小吱
代码简洁,易懂
0
hello_152
hello_152
脱掉裤子就是凉快~
0
lan神
lan神

                                     测试文本框


                                                                        XXX

                                                                        敬上

                                                                           2014.03.31

0
lan神
lan神

      测试文本框


                                                                        XXX

                                                                        敬上

                                                                           2014.03.31

返回顶部
顶部