spring boot server:
package com.example.demo.controller.ssl; import com.example.demo.controller.ProxyController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import serial.MyBaseProto; /** * https://www.cnblogs.com/silyvin/p/12099743.html * Created by joyce on 2019/11/17. */ @Controller @RequestMapping("/json") public class JsonController { @RequestMapping(value = "/testhttps") @ResponseBody public String get() { return "xxx"; } @RequestMapping(value = "/testhttpsPost", method = RequestMethod.POST, produces = "application/json;charset=UTF-8") @ResponseBody public TT post(@RequestBody TT tt) { tt.setPa("12"); tt.setPb("22"); return tt; } private static class TT { String pa; String pb; public String getPa() { return pa; } public void setPa(String pa) { this.pa = pa; } public String getPb() { return pb; } public void setPb(String pb) { this.pb = pb; } } }
package com.example.demo.controller.ssl.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestEncoder;
import io.netty.handler.codec.http.HttpResponseDecoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.util.ReferenceCountUtil;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
/**
* Created by joyce on 2019/12/28.
*/
public class NettyHttpClient {
public static void main(String [] f) {
System.out.println(new NettyHttpClient().send("GET"));
System.out.println(new NettyHttpClient().send("POST"));
}
public String send(String msg) {
try {
Map<String, Object> map = new ConcurrentHashMap<>();
send(msg, map);
return (String)map.get("res");
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
private void send(String msg, Map<String, Object> map) throws Exception, URISyntaxException {
try {
final Bootstrap b = BootStrapManager.newBootStrap();
b.handler(new ClientInit(new MainHandler(map, msg), SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build()));
ChannelFuture f = b.connect("localhost", 8080);
f.channel().closeFuture().sync(); 阻塞
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
private static class ClientInit extends ChannelInitializer<SocketChannel> {
private ChannelInboundHandler handler;
private SslContext context;
public ClientInit(ChannelInboundHandler handler, SslContext context) {
this.handler = handler;
this.context = context;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
if (true) {
ch.pipeline().addLast(context.newHandler(ch.alloc()));
}
ch.pipeline().addLast(new HttpResponseDecoder());
ch.pipeline().addLast(new HttpRequestEncoder());
ch.pipeline().addLast(new HttpObjectAggregator(65535));
ch.pipeline().addLast(handler);
}
}
private static class BootStrapManager {
private static final EventLoopGroup WORKER_GROUP = new NioEventLoopGroup();
private static Bootstrap CLIENT_BOOTSTRAP ;
public static Bootstrap getBootStrap() {
if(CLIENT_BOOTSTRAP == null) {
synchronized (BootStrapManager.class) {
if(CLIENT_BOOTSTRAP == null) {
CLIENT_BOOTSTRAP = newBootStrap();
}
}
}
return CLIENT_BOOTSTRAP;
}
public static Bootstrap newBootStrap() {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(WORKER_GROUP);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, false);
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000);
return bootstrap;
}
}
}
package com.example.demo.controller.ssl.netty;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.HttpObject;
import org.apache.commons.codec.Charsets;
/**
* Created by joyce on 2019/12/28.
*/
@ChannelHandler.Sharable
public class MainHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
private Map<String, Object> map;
private String msg;
public MainHandler(Map _map, String msg) {
this.map = _map;
this.msg = msg;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("active");
HttpRequest request = null;
if(msg.equals("GET"))
request = HttpCreateor.createReqGet("localhost", new URI("/json/testhttps"));
if(msg.equals("POST"))
request = HttpCreateor.createReqPost(
"{"pa":"BeJson","pb":"sss"}".getBytes(), "localhost", new URI("/json/testhttpsPost"));
// 发送
ctx.channel().writeAndFlush(request).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
}
});
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse msg) throws Exception {
System.out.println("read");
if (msg instanceof HttpContent) {
HttpContent httpContent = (HttpContent) msg;
// 字符数组
ByteBuf buf = httpContent.content(); 后自动释放
// 返回
String response = buf.toString(Charsets.UTF_8);
map.put("res", response);
ctx.close();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.channel().close();
}
private static class HttpCreateor {
/**
* 构造HTTP请求
* @return
* @throws Exception
*/
public static HttpRequest createReqGet(String server, URI uri) throws Exception{
String req = "";
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
uri.toASCIIString(), Unpooled.wrappedBuffer(req.getBytes(Charsets.UTF_8)));
// 构建HTTP请求
request.headers().set(HttpHeaders.Names.HOST, server);
request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
request.headers().set("accept-type", Charsets.UTF_8);
request.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/json; charset=UTF-8");
// request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes());
// 返回
return request;
}
public static HttpRequest createReqPost(byte [] body, String server, URI uri) throws Exception{
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST,
uri.toASCIIString(), Unpooled.wrappedBuffer(body));
// 构建HTTP请求
request.headers().set(HttpHeaders.Names.HOST, server);
request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
request.headers().set("accept-type", Charsets.UTF_8);
request.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/json; charset=UTF-8");
request.headers().set(HttpHeaders.Names.CONTENT_LENGTH, request.content().readableBytes());
// 返回
return request;
}
}
}
active
22:23:11.389 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.ssl.util.InsecureTrustManagerFactory - Accepting a server certificate: CN=sun, OU=citi, O=citi, L=sh, ST=sh, C=cn
22:23:11.516 [nioEventLoopGroup-2-1] DEBUG io.netty.handler.ssl.SslHandler - [id: 0x1adda983, /127.0.0.1:63691 => localhost/127.0.0.1:8080] HANDSHAKEN: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
read
xxx
active
22:23:11.592 [nioEventLoopGroup-2-2] DEBUG io.netty.handler.ssl.util.InsecureTrustManagerFactory - Accepting a server certificate: CN=sun, OU=citi, O=citi, L=sh, ST=sh, C=cn
22:23:11.613 [nioEventLoopGroup-2-2] DEBUG io.netty.handler.ssl.SslHandler - [id: 0xbfec2d89, /127.0.0.1:63692 => localhost/127.0.0.1:8080] HANDSHAKEN: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
read
{"pa":"12","pb":"22"}