使用netty做一个简单的http服务器 注解方式获取

首先定义一个注解类,用这个注解类来注解后面要写的servlet类,以便于获取所有的servlet

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Servlet {

    /**
     * url值
     *
     * @return
     */
    String value();

}

在初始化netty服务端的时候将所有的被servlet注解的类存起来

import org.reflections.Reflections;
    // https://mvnrepository.com/artifact/org.reflections/reflections
  //  compile group: 'org.reflections', name: 'reflections', version: '0.9.11'

  /**
     * 获取指定包下被注解的类
     *
     * @param packageName 包全名,如果有多个用","隔开
     * @param clasz       注解类class
     * @return 包下所有被clasz注解的类
     */
    @SuppressWarnings("unchecked")
    private Set<Class<?>> getRequestMappingMethod(String packageName, Class clasz) {

        String[] pname = packageName.split(",");
        Set<Class<?>> classesList = new LinkedHashSet<>();//所有标注了指定注解的class
        Reflections reflections;
        for (int i = 0; i < pname.length; i++) {
            reflections = new Reflections(packageName);
            classesList.addAll(reflections.getTypesAnnotatedWith(clasz));
        }

        return classesList;
    }
 /**
     * 获取被UrlAddress注释的类集合,保存url和具体的servlet类
     *
     * @param packageName 包全名,如果有多个用","隔开
     * @return urlValue ,ObjectServlet
     */
    public Map<String, ObjectServlet> getUrlAddressMap(String packageName) {
    
        Set<Class<?>> classesList = getRequestMappingMethod(packageName, Servlet.class);

        if (classesList.isEmpty())
            return null;

        Map<String, ObjectServlet> list = new HashMap<>();
        classesList.forEach((clasz) -> {

            String value = ((Servlet) clasz.getAnnotation(Servlet.class)).value();
            logger.info("load servlet uri {}", value);
            try {
                list.put(value, (ObjectServlet) clasz.newInstance());
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        });

        return list;
    }

定义一个servlet处理类,以后每个servlet都继承它。

public class ObjectServlet {

    /**
     * 处理get方法
     *
     * @param request
     * @param ctx
     */
    protected void doGet(HttpRequest request, ChannelHandlerContext ctx) {
        sendNotFound(ctx);
    }

    /**
     * 处理post方法,默认找不到
     * 如需另外实现请覆盖此方法,且不要调用super
     *
     * @param request
     * @param ctx
     */
    protected void doPost(HttpRequest request, ChannelHandlerContext ctx) {
        sendNotFound(ctx);
    }

    /**
     * 处理put方法,默认找不到
     * 如需另外实现请覆盖此方法,且不要调用super
     *
     * @param request
     * @param ctx
     */
    protected void doPut(HttpRequest request, ChannelHandlerContext ctx) {
        sendNotFound(ctx);
    }

    /**
     * 处理delete方法,默认找不到
     * 如需另外实现请覆盖此方法,且不要调用super
     *
     * @param request
     * @param ctx
     */
    protected void doDelete(HttpRequest request, ChannelHandlerContext ctx) {
        sendNotFound(ctx);
    }

    /**
     * 根据不同http请求处理不同类型请求
     *
     * @param request
     * @param ctx
     */
    public void process(HttpRequest request, ChannelHandlerContext ctx) throws Exception {

        //http方法类型
        HttpMethod method = request.method();

        if (method == HttpMethod.GET)
            doGet(request, ctx);
        else if (method == HttpMethod.POST)
            doPost(request, ctx);
        else if (method == HttpMethod.PUT)
            doPut(request, ctx);
        else if (method == HttpMethod.DELETE)
            doDelete(request, ctx);
    }

}

比如一个新的servlet

@Servlet("/oop/v1/std/del")
public class Del extends ObjectServlet {

然后在handler里来使用这些地址和servlet

   @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        if (!(msg instanceof HttpRequest))
            return;

        HttpRequest httpRequest = (HttpRequest) msg;
        String uri = httpRequest.uri();


        //uri = test?a=3&b=4  ==>  uri = /test
        QueryStringDecoder queryStringDecoder = new QueryStringDecoder(uri);
        uri = queryStringDecoder.path();


        //根据请求uri获取处理请求的类
        Map<String, ObjectServlet> urlAddressMap = ServletManneger.getUrlAddressMap();


        //处理请求
        if (urlAddressMap.containsKey(uri)) {

            ObjectServlet servlet = urlAddressMap.get(uri);

            servlet.process(httpRequest, ctx);

            ReferenceCountUtil.release(msg);//释放msg,没有往下走的话这个msg需要自己释放
            return;
        }

        //没有的话..
        ResponceErrorUtils.sendNotFound(ctx);//没有对应的uri返回404

        //释放msg
        ReferenceCountUtil.release(msg);//释放msg

    }

附上几个获取参数的工具

  /**
     * 获取地址栏参数
     *
     * @param req
     * @return
     */
    protected Map<String, String> getUriParams(HttpRequest req) {

        Map<String, String> requestParams = new HashMap<>();

        // 处理get请求
        QueryStringDecoder queryStringDecoder = new QueryStringDecoder(req.uri());
        Map<String, List<String>> parame = queryStringDecoder.parameters();
        Iterator<Map.Entry<String, List<String>>> iterator = parame.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, List<String>> next = iterator.next();
            requestParams.put(next.getKey(), next.getValue().get(0));
        }

        return requestParams;

    }

    /**
     * 获取body里参数
     *
     * @param req
     * @return
     */
    protected Map<String, String> getBodyParams(HttpRequest req) {
        Map<String, String> requestParams = new HashMap<>();

        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
                new DefaultHttpDataFactory(false), req);
        List<InterfaceHttpData> postData = decoder.getBodyHttpDatas(); //
        for (InterfaceHttpData data : postData) {
            if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                MemoryAttribute attribute = (MemoryAttribute) data;
                requestParams.put(attribute.getName(), attribute.getValue());
            }
        }

        return requestParams;
    }

    /**
     * 获取body里的数据并转成json
     *
     * @param request
     * @return
     */
    protected JsonObject getJsonBody(HttpRequest request) {

        FullHttpRequest req = (FullHttpRequest) request;

        ByteBuf content = req.content();
        byte[] contentBytes = new byte[content.readableBytes()];
        content.readBytes(contentBytes);
        String string = new String(contentBytes);

        return new JsonParser().parse(string).getAsJsonObject();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值