使用C#快速搭建Rest服务

使用C#快速搭建Rest服务,第1张

为了能够在桌面端软件中简单方便的对外提供RestApi接口,参考Java SpringMVC框架使用C#语言编写了一个简易RestApi服务器框架,目前支持:

- 静态页面处理

- GET/POST/PUT/DELETE请求

- 支持返回JSON

- 支持路由方法

- 支持自定义过滤器

- 服务器返回数据支持gzip压缩

- 支持Component变量自动注入

- 支持Component自动扫描

- GET/POST支持查询参数,POST支持body数据

- 注解支持

  - Component

  - WebFilter

  - RequestMapping

  - Autowired

  - RequestBody

  - RequestParam

new RestApplicationServer().run(new RestConfiguration {

    StaticFileConfigurations = new List<StaticFileConfiguration>() {

        new StaticFileConfiguration("/e", "E:\\"),

        new StaticFileConfiguration("/f", "F:\\")

    }

})

// 将 http://xxxxx.com/e/xxxxx 映射到本地磁盘文件 E:\\xxxxx

// 将 http://xxxxx.com/f/xxxxx 映射到本地磁盘文件 F:\\xxxxx

1.添加Controller

        [Component("PersonController")]

    public class PersonController

    {

        [Autowired]

        public PersonService personService

        private ILogger logger = LoggerFactory.GetLogger()

        [RequestMapping("GET","/api/person/list")]

        public List<Person>GetPersonList()

        {

            return personService.GetPersonList()

        }

        [RequestMapping("GET", "/api/person")]

        public Person GetPerson([RequestParam("id")]int id)

        {

            logger.Debug("id:"+id)

            return personService.GetPerson((int)id)

        }

        [RequestMapping("POST", "/api/person")]

        public string Create([RequestBody] Person person)

        {

            logger.Info("person:" + person.ToString())

            return "ok"

        }

    }

2.添加Service

    [Component("PersonService")]

    public class PersonService

    {

        private ILogger logger = new ConsoleLogger()

        public List<Person>GetPersonList() {

            return TestData.PersonList

        }

        public Person GetPerson(int id)

        {

            return TestData.PersonList.Find(x =>x.id == id)

        }

        public void Create(Person person)

        {

            logger.Debug(person.ToString())

        }

    }

3.启动服务

controller和service上增加Component注解后,服务启动时会进行自动扫描

class Program

{

    static void Main(string[] args)

    {

        new RestApplicationServer().run()

    }

}

1. 添加一个计算接口处理耗时的filter

[WebFilter(1, "/")]

    public class StopWacthFilter : IFilter

    {

        public void Filter(HttpRequest request,ref HttpResponse response, ProcessChain chain, int nextIndex)

        {

            Stopwatch stopwatch = new Stopwatch()

            stopwatch.Start()

            chain.doFilter(request,ref response, nextIndex)

            stopwatch.Stop()

            Console.WriteLine(request.Method + " "+request.Path+ ", 耗时:"+(stopwatch.ElapsedMilliseconds).ToString()+"ms")

        }

    }

自定义filter上增加WebFilter注解后,服务启动时会进行自动扫描

项目地址: https://github.com/13401095975/RestServer

javax.ws.rs.ext.Providers 是JAX-RS 2.0定义的一种辅助接口,其实现类用于辅助REST框架完成过滤和读写拦截的功能,可以使用@Provider 注解标注这些类。Providers接口一共定义了四个方法,分别用来获取MessageBodyReader,MessageBodyWriter,ExceptionMapper,ContextResolver

Jersey 之所以支持那么多中响应实体的传输格式,是因为其底层实体Providers具备的对不同格式的处理能力。Jersey内部提供了丰富的MessageBodyReader和MessageBodyWriter 接口的实现类,用于处理不同格式的表述

如上图,请求流程中存在三种角色,分别是:用户,REST客户端和REST服务器,请求始于请求的发送,止于调用Resonse的readEntity()方法

(1).用户请求提交数据,客户端接收请求,进入第一个扩展点:客户端请求过滤器 ClientRequestFilter 的filter()方法

(2).请求处理过滤完毕后,流程进入第二个扩展点:客户端写拦截器WriterInterceptor实现类的aroundWriterTo() 方法,实现对客户端序列化操作的拦截

(3).客户端消息体写处理器MessageBodyWriter 执行序列化,流程从客户端过渡到服务器端

(4).服务器接收请求,流程进入第三个扩展点:服务器前置请求过滤器ContainerRequestFilter实现类 的filter()方法

(5).过滤器处理完毕后,服务器根据请求匹配资源方法,如果匹配到相应的资源方法,流程进入第四个扩展点:服务器后置请求过滤器ContainerRequestFilter 实现类 的filter() 方法

(6).后置请求过滤器处理完毕后,力促进入第五个扩展点:服务器读拦截器ReaderInterceptor实现类 的aroundReadFrom() 方法,拦截服务器端反序列化操作

(7).服务器消息体读处理器MessageBodyReader 完成对客户端数据流的反序列化,服务器执行匹配的资源方法

(8).REST请求资源的处理完毕后,流程进入第六个扩展点:服务器响应过滤器 ContainerResponseFilter 实现类 的filter() 方法

(9).过滤器处理完毕后,流程进入第七个扩展点:服务器写拦截器WriterInterceptor实现类 的aroundWriterTo() 方法,实现对服务器端序列化到客户端这个操作的拦截

(10).服务器消息体写处理器MessageBodyWriter 执行序列化,流程返回到客户端一侧

(11).客户端接收响应,流程进入第八个扩展点:客户端响应过滤器ClientResponseFilter 实现类 的filter() 方法

(12).过滤处理完毕后,客户端响应实例response 返回到用户一侧,用户执行response.readEntity(),流程进入第九个扩展点:客户端拦截器ReaderInterceptor实现类 的aroundReadFrom() 方法,对客户端反序列化进行拦截

(13).客服端消息体读处理器MessageBodyReader 执行反序列化,将Java类型的对象最终作为readENtity()方法的返回值

JAX-RS-2.0定义的4种过滤器扩展点接口,供开发者实现其业务逻辑,按请求处理流程的先后顺序为:客户端请求过滤器(ClientRequestFilter) ------->服务端请求过滤器(ContainerRequestFilter)-------->服务端响应过滤器(ContainerResponseFilter)——>客户端响应过滤器(ClientResponseFilter)

ClientRequestFilter

ClientResponseFilter

ContainerRequestFilter

ContainerResponseFilter

Jersey 内部实现了几个典型应用的拦截器,他们是成对出现的

ReaderInterceptor

WriterInterceptor

编码解码拦截器(ContentEncoder)

优先级的定义使用注解 @Priority ,优先级的值是一个整数值,对于ContainerReauest,PreMatchContainerRequest,ClientRequest 和读写拦截器 采用升序策略,数值越小,优先级越高;对于ContainerResponse和ClientResponse采用降序策略,数值越大,优先级越高


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/114211.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-12
下一篇2023-03-12

发表评论

登录后才能评论

评论列表(0条)

    保存