关于公司门户网站建设的议案,班级网站主页设计模板,网站权重如何查询,wordpress浏览统计实现简单的Http服务器SpringMvc#xff0c;集成到Spring
1、Http协议
1.1、HTTP 协议请求格式
方法 空格 URL 空格 版本 回车符 换行符头部域名称#xff1a;头部域值 回车符 换行符...头部域名称#xff1a;头部域值 回车符 …实现简单的Http服务器SpringMvc集成到Spring
1、Http协议
1.1、HTTP 协议请求格式
方法 空格 URL 空格 版本 回车符 换行符头部域名称头部域值 回车符 换行符...头部域名称头部域值 回车符 换行符回车符 换行符请求数据利用Tcp接收一条Http请求数据如下
GET /task/findAll?ab HTTP/1.1
Host: localhost:8081
Connection: keep-alive
sec-ch-ua: Google Chrome;v119, Chromium;v119, Not?A_Brand;v24
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: Windows
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application/signed-exchange;vb3;q0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q0.9
完全符合上面的http协议的格式反过来可以根据上面的协议格式解析Http的参数和需要的字段。
解析完后的实体如下
{headers: {Accept: text/html,application/xhtml xml,application/xml;q0.9,image/avif,image/webp,image/apng,*/*;q0.8,application/signed-exchange;vb3;q0.7,Connection: keep-alive,User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36,Sec-Fetch-Site: none,Sec-Fetch-Dest: document,Host: localhost,Accept-Encoding: gzip, deflate, br,content-Type: application/x-www-form-urlencoded,Sec-Fetch-Mode: navigate,sec-ch-ua: \Google Chrome\;v\119\, \Chromium\;v\119\, \Not?A_Brand\;v\24\,sec-ch-ua-mobile: ?0,Cache-Control: max-age0,Upgrade-Insecure-Requests: 1,sec-ch-ua-platform: \Windows\,Sec-Fetch-User: ?1,Accept-Language: zh-CN,zh;q0.9},methodName: GET,protocol: HTTP,queryString: {a: b},uri: /task/findAll,version: 1.1
}1.2、http协议相应格式
版本 空格 状态码 空格 原因短句 回车符 换行符头部域名称头部域值 回车符 换行符...头部域名称头部域值 回车符 换行符回车符 换行符相应正文1.3、请求及相应
public class Test {public static void main(String[] args) {HttpInvoke httpInvoke new HttpInvoke() {Overridepublic Object invoke(RequestEntity entity) {return hello;}};BootstrapServer bootstrapServer new BootstrapServer(8081, httpInvoke);}
}
// HttpInvoke作为请求的回调这里只做简单的回应hello启动8081传送门在httptest包下
2、SpringMvc
2.1、扫描组件包
扫描组件包将每个接口请求封装成MethodHandler
Properties prop PropertyUtils.getClassPathProperties(MVC_CLASSPATH_NAME);
packageScanner new GenericPackagesScanner(ctx.getPackages());
// 1、找到被controller注解标记的类
SetClass? classes packageScanner.getFullyQualifiedClassNameList();
SetClass? webSet new HashSet();
IteratorClass? iterator classes.iterator();
while (iterator.hasNext()) {Class? next iterator.next();if(AnnotationUtils.containsAnyAnnotation(next, ControllerVax.class)) {webSet.add(next);}
}
// 2、解析处理方法
IteratorClass? controller webSet.iterator();
ListMethodHandler handlers new ArrayList();
while (controller.hasNext()) {Class? next controller.next();String commonUrl AnnotationUtils.get(next, UrlMapping.class);ListMethod methods ClassUtils.getMarkedMethod(next, UrlMapping.class);IteratorMethod methodIt methods.iterator();while (methodIt.hasNext()) {Method method methodIt.next();String subUri AnnotationUtils.get(method, UrlMapping.class);MethodHandler methodHandler new MethodHandler();methodHandler.setMethod(method);methodHandler.setMethodURL(subUri);methodHandler.setClazz(next);methodHandler.setClazzUrl(commonUrl);methodHandler.setObj(ctx.getBean(next));methodHandler.setUrl(PathUtils.merge(commonUrl, subUri));methodHandler.setParameters(ClassUtils.getMethodParameters(method));if(handlers.contains(methodHandler)) {throw new MappingExistsException(method mapping exists);}handlers.add(methodHandler);}
}2.2、匹配请求
遍历所有的MethodHandler如果接口上的uri和请求中的uri一直则将参数带进去执行并将结果返回。
IteratorMethodHandler iterator handlers.iterator();while (iterator.hasNext()) {// 接口方法MethodHandler handler iterator.next();if(StringUtils.equals(handler.getUrl(), entity.getUri())) {// controller实例Object bean ctx.getBean(handler.getClazz());Method method handler.getMethod();ListString parameters handler.getParameters();ListParameter parameterType Arrays.asList(method.getParameters());Object[] parameterVal new Object[parameters.size()];for (int i 0; i parameters.size(); i) {// 1、queryStringMapString, String queryString entity.getQueryString();if(queryString ! null queryString.size() 0) {parameterVal[i] ObjectUtils.firstNotNull(queryString.get(parameters.get(i)));}// 2、body-json/form-dataMapString, String body (MapString, String) entity.getBody();if(body ! null body.size() 0) {parameterVal[i] ObjectUtils.firstNotNull(body.get(parameters.get(i)));}if(!ObjectUtils.isSimpleType(parameterType.get(i).getType()) StringUtils.equalsIgnore(entity.getContentType(), Constants.JSON_CONTENT_TYPE_VAL)) {parameterVal[i] JSON.parseObject(entity.getBody().toString(), parameterType.get(i).getType());}}return ObjectUtils.invoke(bean, method, parameterVal);}}3、Spring集成Mybatis
mybatis的代理对象作为Spring组件注入到容器中
JdbcManager jdbcManager new JdbcManager(getJdbcProperties());
packageScanner.setPackages(ctx.getPackages());
this.classes packageScanner.getFullyQualifiedClassNameList();
IteratorClass? iterator this.classes.iterator();
// 2、移除没有被注解标记的类
while (iterator.hasNext()) {Class? clazz iterator.next();if(!AnnotationUtils.containsAnyAnnotation(clazz, GlobalConstants.MAPPER_ANNOTATIONS)) {iterator.remove();continue;}ctx.registry(clazz.getSimpleName(), ProxyUtils.getProxy(clazz, new MapperProxyFactory(jdbcManager)));
}
ctx.refresh(false);4、运行结果 传送门