SpringBoot整合JAX-RS接口

目录

二、创建RESTful资源

三、注册JAX-RS资源

四、修改配置等信息

五、启动SpringBoot程序、访问服务

六、遇到的问题

 七、与feign进行配合使用

1、接口定义

2、接口实现

3、注册资源

4、调用方web服务实现,跟注入普通服务一样

5、启动两个服务,调用


一、增加Jersey依赖

    implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
//    implementation 'jakarta.ws.rs:jakarta.ws.rs-api:2.1.1'implementation 'org.glassfish.jersey.core:jersey-server:3.1.7'implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.7'implementation 'org.springframework.boot:spring-boot-starter-jersey:3.2.7'implementation 'org.javassist:javassist:3.28.0-GA'

二、创建RESTful资源

使用jakarta.ws.rs注解定义RESTful资源

package com.example.service;import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.springframework.stereotype.Component;@Component
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/jersey-service")
public class JerseyService {@GET@Path("test")public String test(){return "jersey demo test";}
}

三、注册JAX-RS资源

三种方式:

1、创建自定义的ResourceConfig

package com.example.service;import jakarta.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;@Configuration
@ApplicationPath("/api")
public class MyApplication extends ResourceConfig {public MyApplication() {// 注册资源类register(JerseyService.class);// 可以注册更多的资源和提供者}
}

访问地址:http://localhost:10002/api/jersey-service/test

加spring.jersey.application-path=demo配置后 不能访问。这两个路径互斥,保留一个即可

2、返回一个ResourceConfig类型的@Bean

package com.example;import com.example.service.JerseyService;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;@EnableFeignClients(basePackages = {"com.example"})
@SpringBootApplication(scanBasePackages = {"com.example"})
public class DemoServiceApplication {public static void main(String[] args) {SpringApplication.run(DemoServiceApplication.class, args);}//    @Bean
//    public MyApplication myApplication(){
//        return new MyApplication();
//    }@Beanpublic ResourceConfig resourceConfig(){ResourceConfig resourceConfig= new ResourceConfig();resourceConfig.register(JerseyService.class);return resourceConfig;}
}

访问地址:http://localhost:10002/jersey-service/test

加spring.jersey.application-path=demo配置后

http://localhost:10002/demo/jersey-service/test

3、配置一组ResourceConfigCustomizer对象

四、修改配置等信息

可以在配置文件application.properties中设置端口路径上下文等

#spring.jersey.application-path=demo
server.port=10002

Springboot默认把Jersey的根路径映射在/*上;如果要更改默认的根路径设置,对于自定义的ResourceConfig方式来说,可以在类上面添加一个@ApplicationPath注解即可。
也可以在application.properties中添加配置spring.jersey.application-path来改变项目的根路径。

五、启动SpringBoot程序、访问服务

六、遇到的问题

1、启动不生效,未增加Springboot集成jersey依赖

解决方案:增加依赖

implementation 'org.springframework.boot:spring-boot-starter-jersey'

2、build报错

增加implementation 'org.springframework.boot:spring-boot-starter-jersey:3.2.7'依赖后build报错

解决方案:改成指定增加依赖

implementation 'org.javassist:javassist:3.28.0-GA'

3、正常启动后访问有问题

2024-07-10T10:53:26.410+08:00 ERROR 22420 --- [demo-service] [io-10002-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Servlet.init() for servlet [com.example.service.MyApplication] threw exceptionjava.lang.NoClassDefFoundError: org/glassfish/jersey/message/internal/NullOutputStreamat org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:311) ~[jersey-container-servlet-core-3.1.7.jar:na]at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) ~[jersey-container-servlet-core-3.1.7.jar:na]at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:339) ~[jersey-container-servlet-core-3.1.7.jar:na]at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) ~[tomcat-embed-core-10.1.25.jar:6.0]at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) ~[tomcat-embed-core-10.1.25.jar:6.0]at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:837) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:588) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.lang.ClassNotFoundException: org.glassfish.jersey.message.internal.NullOutputStreamat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]... 23 common frames omitted

jersey-common3.1.7里面没有这个类org.glassfish.jersey.message.internal.NullOutputStream

把引用的jersey-server包也改成3.1.7,或者都用最新的。之前是指定了3.1.0的版本。总之版本要一致。

4、同时配置spring.jersey.application-path=demo 和 @ApplicationPath("/api")

http://localhost:10002/demo/api/jersey-service/test并不能访问

 七、与feign进行配合使用

配合上次的那个可以结合feign做服务的调用,通用一个接口

Spring Boot单体服务之间用feign调用-CSDN博客

web和service是两个服务。api复用,web通过feign调用service提供的JAX-RS接口。

这是是单体运用做测试,所以配置了url

1、接口定义

package com.example.api;import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;@FeignClient(name ="IDemoService", path = "api/demo-service/", url = "${rootServiceUrl}", primary = false, contextId = "jaxrs")
@Path("/demo-service")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface IDemoService {@GetMapping("test")@GET@Path("test")String test();
}

2、接口实现

package com.example.service;import com.example.api.IDemoService;
import org.springframework.stereotype.Service;@Service
public class DemoService implements IDemoService {@Overridepublic String test() {return "demo service";}
}

3、注册资源

package com.example.service;import jakarta.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Configuration;@Configuration
@ApplicationPath("/api")
public class MyApplication extends ResourceConfig {public MyApplication() {// 注册资源类register(JerseyService.class);register(DemoService.class);// 可以注册更多的资源和提供者}
}

4、调用方web服务实现,跟注入普通服务一样

@RestController
@RequestMapping("/demo")
public class DemoController {@Autowiredprivate IDemoService demoService;@GetMapping("test")public String test(){return demoService.test();}
}

5、启动两个服务,调用

八、JAX-RS说明

JAX-RS(Java API for RESTful Web Services)是Java EE规范的一部分,为构建RESTful Web服务提供了一套统一的API。JAX-RS接口和类主要定义了如何创建和操作RESTful服务。以下是一些核心的JAX-RS接口和注解:

  1. javax.ws.rs.core.Application

    • 用于定义JAX-RS应用程序,可以注册JAX-RS资源和提供者。
  2. javax.ws.rs.Path

    • 注解用于定义资源的URI路径。
  3. HTTP方法注解

    • @GET:处理HTTP GET请求。
    • @POST:处理HTTP POST请求。
    • @PUT:处理HTTP PUT请求。
    • @DELETE:处理HTTP DELETE请求。
    • @PATCH:处理HTTP PATCH请求。
  4. javax.ws.rs.Produces

    • 注解用于指定资源方法可以生成的媒体类型(如application/jsontext/html)。
  5. javax.ws.rs.Consumes

    • 注解用于指定资源方法可以消费的媒体类型。
  6. javax.ws.rs.core.MediaType

    • 类提供定义媒体类型的常量和实用方法。
  7. javax.ws.rs.core.Response

    • 类用于构造和表示HTTP响应,包括状态码和响应体。
  8. javax.ws.rs.GET

    • 除了@GET,还包括@POST@PUT@DELETE等,用于将资源类的方法映射到特定的HTTP方法。
  9. javax.ws.rs.PathParam

    • 注解用于从URI模板中提取参数。
  10. javax.ws.rs.QueryParam

    • 注解用于绑定查询参数。
  11. javax.ws.rs.FormParam

    • 注解用于绑定表单提交的数据。
  12. javax.ws.rs.HeaderParam

    • 注解用于获取HTTP请求头的值。
  13. javax.ws.rs.CookieParam

    • 注解用于获取HTTP cookie的值。
  14. javax.ws.rs.MatrixParam

    • 注解用于处理URI矩阵参数。
  15. javax.ws.rs.core.Requestjavax.ws.rs.core.SecurityContext

    • 接口用于访问HTTP请求的详细信息和安全上下文。
  16. javax.ws.rs.ext.Provider

    • 注解用于标记扩展提供者,如消息体读取器、消息体编写器等。

JAX-RS还定义了其他一些接口和类,用于更高级的功能,如异常处理、拦截器、容器特定的配置等。使用JAX-RS,开发者可以使用注解来简化Web服务的客户端和服务端的开发和部署。基于JAX-RS实现的框架有Jersey、RESTEasy等,它们提供了JAX-RS规范的具体实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html5——表单

目录 表单基本结构 表单标签 常用表单元素 文本框 密码框 邮箱 单选按钮 复选框 文件域 隐藏域 列表框 多行文本域 lable标签 表单按钮 常用表单属性 只读与禁用 placeholder required pattern autofocus autocomplete 用于指定表单是否有自动完…

NoSQL之redis的配置与优化

一、redis数据库的基础介绍与对比 Redis(RemoteDictionaryServer&#xff0c;远程字典型)是一个开源的、使用C语言编写的NoSQL数据库。Redis 基于内存运行并支持持久化&#xff0c;采用 key-value(键值对)的存储形式&#xff0c;是目前分布式架构中不可或缺的一环。 1.非关系…

百日筑基第二十天-一头扎进消息队列3-RabbitMQ

百日筑基第二十天-一头扎进消息队列3-RabbitMQ 如上图所示&#xff0c;RabbitMQ 由 Producer、Broker、Consumer 三个大模块组成。生产者将数据发送到 Broker&#xff0c;Broker 接收到数据后&#xff0c;将数据存储到对应的 Queue 里面&#xff0c;消费者从不同的 Queue 消费数…

我的智能辅助大师-办公小浣熊

一、基本介绍 随着2022年ChatGPT为代表的AI工具对互联网领域进行第一次冲击后&#xff0c;作为一名对编程领域涉足不算特别深的一名程序员&#xff0c;对AI大模型的接触也真的不能算少了&#xff0c;这是时代的必然趋势。在此之前也曾接触过很多的AI工具&#xff0c;他们都能在…

【Vscode】显示多个文件 打开多个文件时实现标签栏多行显示

Vscode显示多个文件&VSCode打开多个文件时实现标签栏多行显示 写在最前面一、解决打开文件的时候只显示一个tab的办法解决办法如下&#xff1a; 二、文件标签栏多行显示设置步骤&#xff1a; &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时…

电脑维护全攻略:让你的“战友”焕发新生

目录 电脑维护全攻略&#xff1a;让你的“战友”焕发新生 引言 方向一&#xff1a;了解你的“战友” 1.1 电脑品牌与型号的选择 1.2 电脑硬件配置的重要性 1.3 电脑软件配置的重要性 方向二&#xff1a;日常维护措施 2.1 定期清理与优化 2.2 保持良好的上网习惯 2.3 …

微服务-注册中心

一. 分布式系统架构与微服务 分布式系统架构和微服务是现代软件开发中常见的两种概念&#xff0c;它们通常结合使用来构建灵活、可扩展和高效的应用程序。 分布式系统架构&#xff1a; 分布式系统架构是指将一个单一的应用程序或服务拆分成多个独立的部分&#xff0c;这些部分…

邮箱表单系统源码

邮箱表单简介 我们的邮箱表单系统是一个简洁高效的工具&#xff0c;旨在为用户提供一种便捷的方式来提交他们的邮箱地址。该系统可以用于订阅新闻通讯、注册活动、获取用户反馈等多种场景。 功能特点&#xff1a; 用户友好的界面&#xff1a; 表单设计简洁直观&#xff0c;用…

t-SNE降维可视化并生成excel文件使用其他画图软件美化

t-sne t-SNE&#xff08;t-分布随机邻域嵌入&#xff0c;t-distributed Stochastic Neighbor Embedding&#xff09;是由 Laurens van der Maaten 和 Geoffrey Hinton 于 2008 年提出的一种非线性降维技术。它特别适合用于高维数据的可视化。t-SNE 的主要目标是将高维数据映射…

修改vscode的字体为等宽字符

在文件——首选项——设置 中 搜索 Editor: Font Family 将内容改为下面的 Consolas, Courier New, monospace 之后重启Vscode就行了

初步探究Rust生态与图形界面编程

引言 Rust作为一种现代的、安全的系统编程语言&#xff0c;自2010年问世以来&#xff0c;逐渐在开发社区中崭露头角。它的内存安全保证、并发处理能力、以及无需垃圾回收机制的高性能特性&#xff0c;使得它成为了开发系统工具、网络服务、以及嵌入式系统的热门选择。然而&…

(五十三)第 8 章 动态存储管理(伙伴系统)

1. 背景说明 2. 示例代码 buddySystem.h // 伙伴系统实现头文件#ifndef BUDDY_SYSTEM_H #define BUDDY_SYSTEM_H#include "errorRecord.h"#define POWER_TIME 10 // 可利用空间总容量的 2 的幂次,子表的个数为 POWER_TIME + 1 #define MAX_USED_BLOCK_NUM 100 //…

我的 Java 面试“打怪升级”之路01

前言 在当今的科技行业&#xff0c;Java 作为一门广泛应用的编程语言&#xff0c;其相关的岗位竞争可谓十分激烈。作为一名求职者&#xff0c;经历 Java 面试就如同一场充满挑战的“打怪升级”游戏。在这里&#xff0c;我想和大家分享一下我在 Java 面试中的一些经历和感悟。 …

SwiftUI 截图(snapshot)视频画面的极简方法

功能需求 在 万物皆可截图:SwiftUI 中任意视图(包括List和ScrollView)截图的通用实现 这篇博文中,我们实现了在 SwiftUI 中截图几乎任何视图的功能,不幸的是它对视频截图却无能为力。不过别着急,我们还有妙招。 在上面的演示图片中,我们在 SwiftUI 中可以随心所欲的截图…

前端Vue组件化实践:打造灵活可维护的地址管理组件

随着前端技术的不断演进&#xff0c;复杂度和开发难度也随之上升。传统的一体化开发模式使得每次小小的修改或功能增加都可能牵一发而动全身&#xff0c;严重影响了开发效率和维护成本。组件化开发作为一种解决方案&#xff0c;通过模块化、独立化的开发方式&#xff0c;实现了…

【java算法专场】滑动窗口(下)

目录 水果成篮 算法分析 算法步骤 示例 算法代码 找到字符串中所有字母异位词 算法分析 算法步骤 示例 算法代码 优化 算法代码 串联所有单词的子串 算法分析 算法步骤 示例 算法代码 最小覆盖子串 算法分析 算法步骤 示例 算法代码 算法分析 这道题其实…

AI绘画Stable Diffusion 自制素材工具: layerdiffusion插件—透明背景生成工具

大家好&#xff0c;我是设计师阿威 今天给大家分享一款AI绘画的神级插件—LayerDiffusion。 Layerdiffusion是一个用于stable-diffusion-webui 的透明背景生成&#xff08;不是生成图再工具扣图&#xff0c;是直接生成透明背景透明图像&#xff09;插件扩展&#xff0c;它可以…

【Linux 文件读写描述符重定向 Linux 一切皆文件缓冲区】

文章目录 一、文件的读写操作二、文件描述符三、文件重定向四、理解 Linux 一切皆文件五、文件缓冲区 一、文件的读写操作 文件内容属性 当文件没有被操作的时候&#xff0c;一般文件还是在磁盘当中 文件操作文件内容的操作文件属性的操作&#xff0c;文件操作有可能即改变内容…

《python程序语言设计》2018版第5章第55题利用turtle黑白棋盘。可读性还是最重要的。

今天是我从2024年2月21日开始第9次做《python程序语言设计》作者梁勇 第5章 从2019年夏天的偶然了解python到2020年第一次碰到第5章第一题。彻底放弃。再到半年后重新从第一章跑到第五章&#xff0c;一遍一遍一直到今天2024.7.14日第9次刷第五章。 真的每次刷完第五章感觉好像…

【JavaScript】解决 JavaScript 语言报错:Uncaught SyntaxError: Unexpected token

文章目录 一、背景介绍常见场景 二、报错信息解析三、常见原因分析1. 缺少必要的语法元素2. 使用了不正确的字符或符号3. JSON 格式错误4. 字符串未正确闭合 四、解决方案与预防措施1. 检查语法元素2. 正确使用符号和字符3. 修正 JSON 格式4. 字符串闭合 五、示例代码和实践建议…