• Springboot 整合Jersey


      在查看EurekaServer 服务端代码时偶然看到Jersey这个东西,简单记录下。

    1. 简介

      Jersey是一个RESTFUL请求服务JAVA框架,与常规的JAVA编程使用的struts框架类似,它主要用于处理业务逻辑层。

      1.X的版本是sun公司提供的独立的jar包,在2.X版本中已经将jersey融合到JavaSE中,在javax.ws.rs.*包中。

      参考:https://eclipse-ee4j.github.io/jersey/

    2. Springboot 整合Jersey

    参考: https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/htmlsingle/#boot-features-jersey

    1. 引入依赖

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jersey</artifactId>
            </dependency>

    2. 编写资源(在Jersey 中一切借口皆为资源)

    package cn.xm.controller;
    
    import cn.xm.bean.common.Message;
    import cn.xm.mapper.common.MessageMapper;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.ws.rs.*;
    import java.util.List;
    
    @Component
    @Path("/{version}/messages") // 类似SpringMVC,这里可以不写, 也可以用通配符
    //@Path("/messages") // 类似SpringMVC,这里可以不写, 也可以用通配符
    @Slf4j
    //@Produces({"application/xml", "application/json"}) // 标记可生产的数据类型, 也就是客户端Accept 的类型
    //@Consumes({"application/json", "application/xml", "*/*"}) // 标记可以接受的类型, 也就是Content-Type
    public class MessageResource {
    
        @Autowired
        private MessageMapper messageMapper;
    
        @GET
        @Path("/index")
        public String index() {
            return "cn.xm.controller.UserResource.index";
        }
    
        @GET
        @Path("/get")
        public Message get() {
            List<Message> users = messageMapper.findAll();
            return users.get(0);
        }
    
        @GET
        @Path("/get2")
        public Message get2() {
            List<Message> users = messageMapper.findAll();
            return users.get(0);
        }
    
        @GET
        @Path("/get3")
        public Message get3() {
            List<Message> users = messageMapper.findAll();
            return users.get(0);
        }
    
        @GET
        @Path("/get4/{pkUser}")
        public Message get4(@PathParam("pkUser") Integer pkUser, @PathParam("version") String version, @QueryParam("status") String status, @HeaderParam("my_token") String my_token) {
            log.info("pkUser: {}", pkUser);
            log.info("version: {}", version);
            log.info("status: {}", status);
            log.info("my_token: {}", my_token);
            return messageMapper.findOne(pkUser);
        }
    
    }

    3. 注册资源

    package cn.xm.config;
    
    import cn.xm.controller.MessageResource;
    import org.glassfish.jersey.server.ResourceConfig;
    import org.springframework.stereotype.Component;
    
    import javax.ws.rs.ApplicationPath;
    
    @Component
    @ApplicationPath("/testJersey")
    public class JerseyConfig extends ResourceConfig {
    
        public JerseyConfig() {
            register(MessageResource.class);
    
            // 还可以注册过滤器等
    
            // 注册包
    //        packages("xxx")
        }
    }

      这里需要注意,ApplicationPath 是指定Jersey 开始的路径,默认是/*。  当我们指定为/testJersey 之后,默认会被重置为/testJersey/*

    4. Message 实体类

    import cn.xm.bean.AbstractSequenceEntity;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.xml.bind.annotation.XmlRootElement;
    
    //公共信息表
    @Entity
    @XmlRootElement
    public class Message extends AbstractSequenceEntity {
    
        private String name;
    
        /**
         * 用于所属区域
         */
        private String messageblank;
    
        @Column(length = 20000)
        private String content;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name == null ? null : name.trim();
        }
    
        public String getMessageblank() {
            return messageblank;
        }
    
        public void setMessageblank(String messageblank) {
            this.messageblank = messageblank == null ? null : messageblank.trim();
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content == null ? null : content.trim();
        }
    }

    5. 启动后测试:(会根据我们接受的类型自动返回XML或者JSON)

    j@x MINGW64 /e/ideaspace
    $ curl --header 'Accept: application/json' http://localhost:8088/testJersey/v1/messages/index
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100    35  100    35    0     0   1666      0 --:--:-- --:--:-- --:--:--  1842cn.xm.controller.UserResource.index
    
    j@x MINGW64 /e/ideaspace
    $ curl --header 'Accept: application/json' http://localhost:8088/testJersey/v1/messages/get
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   246  100   246    0     0  11181      0 --:--:-- --:--:-- --:--:-- 11714{"creator":"admin","createtime":"2021-03-11","remark1":null,"remark2":null,"remark3":null,"properties":null,"propertiesMap":{},"id":1,"name":"姹傜編椋?,"messageblank":"缇庨�","content":"鍖椾含鍝�噷鏈夊ソ鍚冪殑锛?,"createtimeStr":"2021-03-11"}
    
    j@x MINGW64 /e/ideaspace
    $ curl --header 'Accept: application/xml' http://localhost:8088/testJersey/v1/messages/get
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   261  100   261    0     0  13050      0 --:--:-- --:--:-- --:--:-- 13736<?xml version="1.0" encoding="UTF-8" standalone="yes"?><message><createtime>2021-03-11T10:38:19+08:00</createtime><creator>admin</creator><id>1</id><content>鍖椾含鍝�噷鏈夊ソ鍚冪殑锛?/content><messageblank>缇庨�</messageblank><name>姹傜編椋?/name></message>
    
    j@x MINGW64 /e/ideaspace
    $ curl --header 'Accept: application/xml' --header 'my_token: 111222' http://localhost:8088/testJersey/v1/messages/get4/1?status=1234
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   261  100   261    0     0   9000      0 --:--:-- --:--:-- --:--:--  9321<?xml version="1.0" encoding="UTF-8" standalone="yes"?><message><createtime>2021-03-11T10:38:19+08:00</createtime><creator>admin</creator><id>1</id><content>鍖椾含鍝�噷鏈夊ソ鍚冪殑锛?/content><messageblank>缇庨�</messageblank><name>姹傜編椋?/name></message>

    控制台日志如下:

    2021-03-18 09:21:12.383  INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource         : pkUser: 1
    2021-03-18 09:21:12.383  INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource         : version: v1
    2021-03-18 09:21:12.383  INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource         : status: 1234
    2021-03-18 09:21:12.383  INFO 32328 --- [nio-8088-exec-4] cn.xm.controller.MessageResource         : my_token: 111222

    3. 自动配置简单查看

    参考:org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration 类

    org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration#jerseyServletRegistration 这里注册一个Servlet:

        @Bean
        @ConditionalOnMissingBean(name = "jerseyServletRegistration")
        @ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "servlet", matchIfMissing = true)
        public ServletRegistrationBean jerseyServletRegistration() {
            ServletRegistrationBean registration = new ServletRegistrationBean(
                    new ServletContainer(this.config), this.path);
            addInitParameters(registration);
            registration.setName(getServletRegistrationName());
            registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup());
            return registration;
        }

      这里注册的这个ServletContainer 是一个Servlet 也是一个Filter。在下面方法注册为Filter

        @Bean
        @ConditionalOnMissingBean(name = "jerseyFilterRegistration")
        @ConditionalOnProperty(prefix = "spring.jersey", name = "type", havingValue = "filter")
        public FilterRegistrationBean jerseyFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new ServletContainer(this.config));
            registration.setUrlPatterns(Arrays.asList(this.path));
            registration.setOrder(this.jersey.getFilter().getOrder());
            registration.addInitParameter(ServletProperties.FILTER_CONTEXT_PATH,
                    stripPattern(this.path));
            addInitParameters(registration);
            registration.setName("jerseyFilter");
            registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
            return registration;
        }

      所以Jersey 相关的入口就是这个ServletContainer类。 可以理解为也是进入service 之后进行一系列判断之后获取到对应的Resource 进行处理,Resource 可以理解为Handler。

    【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】
  • 相关阅读:
    区块链技术术语表
    以太坊客户端Geth命令用法-参数详解
    智能合约开发环境搭建及Hello World合约
    以太坊是什么
    比特币区块结构Merkle树及简单支付验证分析
    非对称加密技术- RSA算法数学原理分析
    验证APNS证书的有效性
    十八般武艺之 Runloop
    iOS 所有设备一览 && CoreFoundation源码
    [User Defaults] Failed to read values in CFPrefsPlistSource (iOS 10)
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/14553622.html
Copyright © 2020-2023  润新知