All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.dubboclub.restful.export.RestfulHandler Maven / Gradle / Ivy

package net.dubboclub.restful.export;

import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.remoting.http.HttpHandler;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.dubboclub.restful.exception.NotFoundServiceException;
import net.dubboclub.restful.export.mapping.*;
import net.dubboclub.restful.export.mapping.ServiceHandler;
import net.dubboclub.restful.modal.RestfulPackage;
import net.dubboclub.restful.util.ClassUtils;
import net.dubboclub.restful.util.RestfulConstants;
import org.apache.commons.lang.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Enumeration;

/**
 * Created by bieber on 2015/11/5.
 */
public class RestfulHandler implements HttpHandler {

    private ServiceMappingContainer serviceMappingContainer;

    private Logger logger = LoggerFactory.getLogger(RestfulHandler.class);

    private String contextPath = "/";

    private static final String SERVICES_PATH="services";

    public RestfulHandler(ServiceMappingContainer serviceMappingContainer,String contextPath) {
        this.serviceMappingContainer = serviceMappingContainer;
        this.contextPath = contextPath;
    }

    /**
     * 所有restful的入口
     * http://ip:port/contextpath/${path}/${method}/${version}/${group}
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String requestUri = request.getRequestURI();
        if(!StringUtils.contains(requestUri,contextPath)){
            response.sendError(404);
            return;
        }
        requestUri = requestUri.substring(requestUri.indexOf(contextPath)+contextPath.length());
        String[] fragments = StringUtils.split(requestUri,"/");
        if(fragments.length==0){
            logger.error("request uri ["+requestUri+"] is incorrect.");
            response.sendError(404);
            return;
        }
        String path = fragments[0];
        //返回所有注册的服务列表,帮助查看服务信息
        if(path.equalsIgnoreCase(SERVICES_PATH)){
            serviceMappingContainer.writeServiceHtml(response.getOutputStream());
            return;
        }
        RequestEntity entity = null;
        byte[] requestContent = copyBytesFromRequest(request);
        JSONObject jsonObject=null;
        try{
            jsonObject  = (JSONObject) JSON.parse(requestContent);
            entity = new RequestEntity(jsonObject);
        }catch (Exception e){
            logger.error("Fail to parse request content to json,request uri ["+requestUri+"]");
            response.sendError(500);
            return;
        }
        if(jsonObject==null){
            response.sendError(500);
            return;
        }
        if(entity==null){
            entity = new RequestEntity();
        }
        if(fragments.length>=2){
            entity.setMethod(fragments[1]);
        }
        if(fragments.length>=3&&!fragments[2].equals(RestfulConstants.ALL)){
            entity.setVersion(fragments[2]);
        }
        if(fragments.length>=4&&!fragments[3].equals(RestfulConstants.ALL)){
            entity.setGroup(fragments[3]);
        }
        readAttachment(request);
        try{
            ServiceHandler serviceHandler = serviceMappingContainer.mappingService(path, entity);
            MethodHandler methodHandler = serviceHandler.mapping(entity);

            RestfulPackage restfulPackage = (RestfulPackage)  JSON.toJavaObject(jsonObject,methodHandler.getArgType());
            if(methodHandler!=null){
                try {
                    Object ret = methodHandler.invoke(restfulPackage);
                    rendingResponse(response,ret);
                } catch (Exception e) {
                    logger.error("Fail to invoke method ["+methodHandler.toString()+"]",e);
                    response.sendError(500);
                    return;
                }
            }else{
                logger.warn("Not found method in service ["+serviceHandler.getServiceType().getName()+"],request entity ["+entity.toString()+"].");
                response.sendError(404);
                return;
            }
        }catch (NotFoundServiceException e){
            logger.error("Not found service for request uri ["+requestUri+"]",e);
            response.sendError(404);
            return;
        }
    }



    private void readAttachment(HttpServletRequest request){
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            if(name.startsWith(RestfulConstants.RESTFUL_HEADER_KEY_PREFIX)){
                RpcContext.getContext().setAttachment(name.replaceFirst(RestfulConstants.RESTFUL_HEADER_KEY_PREFIX,""),request.getHeader(name));
            }
        }
    }


    private void rendingResponse(HttpServletResponse response,Object ret) throws IOException {
        if(ret!=null){
            try {
                response.setContentType("application/json");
                if(ClassUtils.isBasicType(ret.getClass())){
                    response.getOutputStream().write(ret.toString().getBytes());
                }else{
                    response.getOutputStream().write(JSON.toJSONBytes(ret));
                }
            } catch (IOException e) {
                logger.error("Fail to rending response",e);
                response.sendError(500);
            }
        }
    }

    /**
     * 将request body的byte字节数组复制到内存中
     * @param httpServletRequest
     * @return
     * @throws IOException
     */
    private byte[] copyBytesFromRequest(HttpServletRequest httpServletRequest) throws IOException {
        InputStream inputStream = httpServletRequest.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int offset=-1;
        while((offset=inputStream.read(buffer,0,1024))>0){
            byteArrayOutputStream.write(buffer,0,offset);
        }
        return byteArrayOutputStream.toByteArray();
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy