// 定义两个注解类
public @interface Controller {
String value() default "";
}
public @interface GetMapping {
String value() default "";
}
// 标注controller对象
@Controller
public class IndexController {
// 自定义注解
@GetMapping("/index")
public String index(String name){
return "Welcome " + name;
}
}
// 封装了资源类
public class Request {
private Class[] parameterTypes;
private Object returnType;
private Method method;
private Class clazz;
}
// 暴露一个端口,并且解析所有的controller
public class Server {
private int port = 8080;
private static final Map<String, Request> GET_MAPPING = new HashMap<>();
private static String bashScanPackage = "com.data.controller";
private ClassLoader classLoader = Server.class.getClassLoader();
private ServerSocket socket;
/**
* 初始化
*
* @throws ClassNotFoundException
*/
private void init() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
URL url = classLoader.getResource(bashScanPackage.replaceAll("\\.", "/"));
String filePath = url.getFile();
File file = new File(filePath);
for (String s : file.list()) {
s = s.substring(0, s.indexOf("."));
Class clazz = Class.forName(bashScanPackage + "." + s);
if (!clazz.isAnnotationPresent(Controller.class)) {
continue;
}
Method[] methods = clazz.getDeclaredMethods();
for (Method m : methods) {
GetMapping getMapping = m.getAnnotation(GetMapping.class);
if (getMapping == null) {
continue;
}
Request req = new Request();
req.setMethod(m);
req.setClazz(clazz);
req.setParameterTypes(m.getParameterTypes());
req.setReturnType(m.getReturnType());
GET_MAPPING.put(getMapping.value(), req);
}
}
}
private void start() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
init();
socket = new ServerSocket(port);
System.out.println("server startup, current port:" + port);
while (true) {
Socket client = socket.accept();
processor(client);
}
}
private void processor(Socket client) throws IOException {
InputStream is = client.getInputStream();
OutputStream os = client.getOutputStream();
String[] res = requestProcessor(is);
if (res == null || res.length < 3) {
responseProcessor(os, "403", "Request Bad!", "");
destroy(client, is, os);
return;
}
String method = res[0];
String url = res[1];
String protocol = res[2];
System.out.println(protocol + "::" + method + "::" + url);
if (!GET_MAPPING.containsKey(url)) {
responseProcessor(os, "404", "404-Not Found!", "");
destroy(client, is, os);
return;
}
Request request = GET_MAPPING.get(url);
Object o;
try {
o = request.getMethod().invoke(request.getClazz().newInstance(), "lisa");
responseProcessor(os, "200", "OK", o.toString());
} catch (Exception e) {
e.printStackTrace();
responseProcessor(os, "501", "Server unavailable!", "");
} finally {
destroy(client, is, os);
}
}
private void destroy(Socket client, InputStream is, OutputStream os) throws IOException {
os.flush();
os.close();
is.close();
client.close();
}
private void responseProcessor(OutputStream outputStream, String code, String desc, String data) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1")
.append(code + "\t")
.append(desc + "\n")
.append("Content-Type: text/html;\n")
.append("\r\n")
.append(data);
outputStream.write(sb.toString().getBytes());
}
private String[] requestProcessor(InputStream inputStream) throws IOException {
try {
//拿到HTTP协议内容
String content = "";
byte[] buff = new byte[1024];
int len;
if ((len = inputStream.read(buff)) != -1) {
content = new String(buff, 0, len);
}
String line = content.split("\\n")[0];
return line.split("\\s");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
Server server = new Server();
server.start();
}
基于netty的改造
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
private void start() throws Exception {
init();
// Boss线程
EventLoopGroup bossGroup = new NioEventLoopGroup();
// Worker线程
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// Netty服务
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
// 客户端初始化处理
protected void initChannel(SocketChannel client) {
client.pipeline().addLast(new HttpResponseEncoder());
client.pipeline().addLast(new HttpRequestDecoder());
// 业务逻辑处理
client.pipeline().addLast(new WebServerHandler(GET_MAPPING));
}
}
.option(ChannelOption.SO_BACKLOG, 10)
// 针对子线程的配置 保持长连接
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 启动服务器
ChannelFuture f = server.bind(port).sync();
System.out.println("server startup, listener port:" + port);
f.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭线程池
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
//业务处理
public class WebServerHandler extends ChannelInboundHandlerAdapter {
private ChannelHandlerContext channelHandlerContext;
private HttpRequest request;
private Map<String, Request> GET_MAPPING;
public WebServerHandler(Map<String, Request> GET_MAPPING) {
this.GET_MAPPING = GET_MAPPING;
}
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpRequest) {
channelHandlerContext = ctx;
request = (HttpRequest) msg;
String url = request.uri();
int len = request.uri().indexOf("?");
if (len != -1) {
url = request.uri().substring(0, len);
}
if (!GET_MAPPING.containsKey(url)) {
responseProcessor("404-Not Found!");
return;
}
Request source = GET_MAPPING.get(url);
Object obj = source.getMethod().invoke(source.getClazz().newInstance(), null);
responseProcessor((String) obj);
}
}
private void responseProcessor(String data) throws UnsupportedEncodingException {
FullHttpResponse resp = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
Unpooled.wrappedBuffer(data.getBytes("UTF-8")));
resp.headers().set("Content-Type", "text/html;");
channelHandlerContext.write(resp);
channelHandlerContext.flush();
channelHandlerContext.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
}
来源:oschina
链接:https://my.oschina.net/u/2486137/blog/3157674