HTTPサーバーとして| Webサービスを作成する実際の戦闘シリーズ(5)---でのAndroidのアプリケーション開発におけるネッティー

バック第一章の始まりから見て示唆して記事を読みます

この一連の記事

ネッティーは、Androidは、Webサーバプロセスとして動作することを可能にするWebサービスを作成することができさえも、ソケットの需要を処理する強力な追加ため息しなければならなかったGETPOSTなどの要求に...

まず、HTTPサービスを作成します

public class HttpServer {
    private static final String TAG = "HttpServer";
    //服务开启在的端口
    public static final int PORT = 7020;

    public void startHttpServer() {
        try {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            // http服务器端对request解码
                            pipeline.addLast(new HttpRequestDecoder());
                            // http服务器端对response编码
                            pipeline.addLast(new HttpResponseEncoder());
                            // 在处理POST消息体时需要加上
                            pipeline.addLast(new HttpObjectAggregator(65536));
                            // 处理发起的请求
                            pipeline.addLast(new HttpServerHandler());
                        }
                    });
            //绑定服务在7020端口上
            b.bind(new InetSocketAddress(PORT)).sync();
            Log.d(TAG, "HTTP服务启动成功 PORT=" + PORT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • HTTPサービスを開始
new HttpServer().startHttpServer();

そして我々は、接続ソケットを添加する前に、コードを見つけることができる書き込みDecoderEncoder一貫性のない、本明細書で使用するエンコーダおよびデコーダに特にパッケージ化網状HTTP要求であります

  • ラン効果
    ここに画像を挿入説明

第二には、中にHttpServerHandlerHTTPリクエスト処理で受信しました

public class HttpServerHandler extends ChannelInboundHandlerAdapter {
    private static final String TAG = "HttpServerHandler";

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!(msg instanceof FullHttpRequest)) {
            Log.e(TAG, "未知请求:" + msg.toString());
            return;
        }
        //获取请求的信息
        FullHttpRequest httpRequest = (FullHttpRequest) msg;
        String path = httpRequest.uri();
        HttpMethod method = httpRequest.method();
        
        Log.d(TAG, "==================接收到了请求==================");
        Log.d(TAG, "route = " + route);
        Log.d(TAG, "method = " + method);
    }
}
  • ここに私たちのコンピュータは、ブラウザを使用できるように、私はAndroidのエミュレータで実行されていた項目があるので、あなたは、ポート転送を行うには、コンソールで次のコマンドを入力する必要があるlocalhost:7020HTTPサービスへのアクセスに
//7020 就是你要转发的端口
adb forward tcp:7020 tcp:7020
  • ブラウザに入力します。localhost:7020/testビューの次のポイントを
    ここに画像を挿入説明
  • 我々は唯一のリクエストを受信しましたが、その要求はまた、要求につながった結果が、で完了することができなかったが返されませんでした上記の请求中状態
    ここに画像を挿入説明

HTTP要求に応答して第三に、

  • 接続が唯一書き込む必要がありFullHttpResponse、次のコードに
ByteBuf byteBuf = Unpooled.copiedBuffer(Result.ok("请求成功").getBytes());
response(ctx, "text/json;charset=UTF-8", byteBuf, HttpResponseStatus.OK);
/**
 * 响应请求结果
 *
 * @param ctx     	  返回
 * @param contentType 响应类型
 * @param content 	  消息
 * @param status      状态
 */
private void response(ChannelHandlerContext ctx, String contentType, ByteBuf content, HttpResponseStatus status) {
    FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
    response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
    ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
}

これまで、基本的なHTTPサービスが駆けてきた、残りはパラメータやプロセスの要求を解決するために開始され、

第四に、いくつかの例は、データまたはJSONに応答してリクエストのパラメータおよび応答画像データを取得する方法を示し、以下に与えられます

  • HttpServerHandler类
public class HttpServerHandler extends ChannelInboundHandlerAdapter {
    private static final String TAG = "HttpServerHandler";

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!(msg instanceof FullHttpRequest)) {
            Log.e(TAG, "未知请求:" + msg.toString());
            return;
        }
        FullHttpRequest httpRequest = (FullHttpRequest) msg;
        String path = httpRequest.uri();
        HttpMethod method = httpRequest.method();

        String route = parseRoute(path);
        Map<String, Object> params = new HashMap<>();
        if (method == HttpMethod.GET) {
            parseGetParams(params, path);
        } else if (method == HttpMethod.POST) {
            parsePostParams(params, httpRequest);
        } else {
            //错误的请求方式
            ByteBuf byteBuf = Unpooled.copiedBuffer(Result.error("不支持的请求方式").getBytes());
            response(ctx, "text/json;charset=UTF-8", byteBuf, HttpResponseStatus.BAD_REQUEST);
        }
        Log.d(TAG, "==================接收到了请求==================");
        Log.d(TAG, "route = " + route);
        Log.d(TAG, "method = " + method);
        Log.d(TAG, "params = " + params.toString());

        handlerRequest(ctx, route, params);
    }

    /**
     * 处理每个请求
     */
    private void handlerRequest(ChannelHandlerContext ctx, String route, Map<String, Object> params) throws Exception {
        switch (route) {
            case "login":
                ByteBuf login;
                if ("admin".equals(params.get("name")) && "123".equals(params.get("psd"))) {
                    login = Unpooled.copiedBuffer(Result.ok("登录成功").getBytes());
                } else {
                    login = Unpooled.copiedBuffer(Result.error("登录失败").getBytes());
                }
                response(ctx, "text/json;charset=UTF-8", login, HttpResponseStatus.OK);
                break;
            case "getImage":
                //返回一张图片
                ByteBuf image = getImage(new File("/storage/emulated/0/Android/data/com.azhon.nettyhttp/cache/test.jpg"));
                response(ctx, "image/jpg", image, HttpResponseStatus.OK);
                break;
            case "json":
    			ByteBuf json = Unpooled.copiedBuffer(Result.ok("测试post请求成功").getBytes());
    			response(ctx, "text/json;charset=UTF-8", json, HttpResponseStatus.OK);
    			break;
            default:
                ByteBuf error = Unpooled.copiedBuffer(Result.error("未实现的请求地址").getBytes());
                response(ctx, "text/json;charset=UTF-8", error, HttpResponseStatus.BAD_REQUEST);
                break;
        }
    }

    /**
     * 解析Get请求参数
     */
    private void parseGetParams(Map<String, Object> params, String path) {
        //拼接成全路径好取参数
        Uri uri = Uri.parse("http://127.0.0.1" + path);
        Set<String> names = uri.getQueryParameterNames();
        Iterator<String> iterator = names.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            params.put(key, uri.getQueryParameter(key));
        }
    }

    /**
     * 解析Post请求参数,以提交的body为json为例
     */
    private void parsePostParams(Map<String, Object> params, FullHttpRequest httpRequest) throws JSONException {
        ByteBuf content = httpRequest.content();
        String body = content.toString(CharsetUtil.UTF_8);
        JSONObject object = new JSONObject(body);
        Iterator<String> keys = object.keys();
        while (keys.hasNext()) {
            String key = keys.next();
            params.put(key, object.opt(key));
        }
    }

    /**
     * 解析调用的接口(路由地址)
     */
    private String parseRoute(String path) {
        if (path.contains("?")) {
            String uri = path.split("\\?")[0];
            return uri.substring(1);
        } else {
            return path.substring(1);
        }
    }


    /**
     * 返回图片
     */
    private ByteBuf getImage(File file) throws Exception {
        ByteBuf byteBuf = Unpooled.buffer();
        FileInputStream stream = new FileInputStream(file);
        int len;
        byte[] buff = new byte[1024];
        while ((len = stream.read(buff)) != -1) {
            byteBuf.writeBytes(buff, 0, len);
        }
        return byteBuf;
    }

    /**
     * 响应请求结果
     *
     * @param ctx         返回
     * @param contentType 响应类型
     * @param content     消息
     * @param status      状态
     */
    private void response(ChannelHandlerContext ctx, String contentType, ByteBuf content, HttpResponseStatus status) {
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, contentType);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}
  • 結果クラス、データはJSONのツールを返さ
public class Result {
    /**
     * 响应请求c成功
     */
    public static String ok(String msg) {
        JSONObject object = new JSONObject();
        try {
            object.put("code", 100);
            object.put("msg", msg);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return object.toString();
    }

    /**
     * 响应请求失败
     */
    public static String error(String msg) {
        JSONObject object = new JSONObject();
        try {
            object.put("code", 101);
            object.put("msg", msg);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return object.toString();
    }
}

第五は、テストインタフェースアドレスに上記使用します

GET		http://localhost:7020/login?name=admin&psd=123  登录
GET		http://localhost:7020/getImage					获取图片
POST	http://localhost:7020/json						提交json数据
  • POSTメソッドは、ここで使用されpostman、以下のように、シミュレートするには:
    ここに画像を挿入説明

第六に、業績

ここに画像を挿入説明

一般的な使用の下ネッティーは、興味のある学生を試すことができ、HTTPサービスを作成することは非常に簡単ではまだです。コードは、記事に掲載されているデモをアップロードしない(デモもアップロード統合emmmmをダウンロードしてください...)

公開された140元の記事 ウォンの賞賛546 ビュー540 000 +

おすすめ

転載: blog.csdn.net/a_zhon/article/details/101226878