Spring整合CXF,发布RSETful 风格WebService

import javax.ws.rs.core.MediaType;

import com.hoo.entity.MapBean;

import com.hoo.entity.User;

import com.hoo.entity.Users;

/*

注释(Annotation):在 javax.ws.rs.* 中定义,是 JAX-RS (JSR 311) 规范的一部分。

@Path:定义资源基 URI。由上下文根和主机名组成,资源标识符类似于 http://localhost:8080/RESTful/rest/hello。

@GET:这意味着以下方法可以响应 HTTP GET 方法。

@Produces:以纯文本方式定义响应内容 MIME 类型。

@Context: 使用该注释注入上下文对象,比如 Request、Response、UriInfo、ServletContext 等。

@Path(“{contact}”):这是 @Path 注释,与根路径 “/contacts” 结合形成子资源的 URI。

@PathParam(“contact”):该注释将参数注入方法参数的路径,在本例中就是联系人 id。其他可用的注释有 @FormParam、@QueryParam 等。

@Produces:响应支持多个 MIME 类型。在本例和上一个示例中,APPLICATION/XML 将是默认的 MIME 类型。

*/

/**

* function: CXF RESTful风格WebService

* @author hoojo

* @createDate 2012-7-20 下午01:23:04

* @file RESTSampleSource.java

* @package com.hoo.service

* @project CXFWebService

* @blog http://blog.csdn.net/IBM_hoojo

* @email hoojo_@126.com

* @version 1.0

*/

@Path(value = “/sample”)

public interface RESTSample {

@GET

@Produces(MediaType.TEXT_PLAIN)

public String doGet();

@GET

@Produces(MediaType.TEXT_PLAIN)

@Path(“/request/{param}”)

public String doRequest(@PathParam(“param”) String param,

@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse);

@GET

@Path(“/bean/{id}”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public User getBean(@PathParam(“id”) int id);

@GET

@Path(“/list”)

@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })

public Users getList();

@GET

@Path(“/map”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public MapBean getMap();

/*

@Consumes:声明该方法使用 HTML FORM。

@FormParam:注入该方法的 HTML 属性确定的表单输入。

@Response.created(uri).build(): 构建新的 URI 用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。

您可以使用 http://localhost:8080/Jersey/rest/contacts/ 访问新联系人

*/

@POST

@Path(“/postData”)

public User postData(User user) throws IOException;

@PUT

@Path(“/putData/{id}”)

@Consumes(MediaType.APPLICATION_XML)

public User putData(@PathParam(“id”) int id, User user);

@DELETE

@Path(“/removeData/{id}”)

public void deleteData(@PathParam(“id”) int id);

}

二、RESTSample接口的实现,这里我们只是简单的实现下,并不是涉及实际的具体业务

package com.hoo.service;

import java.io.IOException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.ws.rs.DELETE;

import javax.ws.rs.GET;

import javax.ws.rs.POST;

import javax.ws.rs.PUT;

import javax.ws.rs.Path;

import javax.ws.rs.PathParam;

import javax.ws.rs.Produces;

import javax.ws.rs.core.Context;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Request;

import javax.ws.rs.core.UriInfo;

import com.hoo.entity.MapBean;

import com.hoo.entity.User;

import com.hoo.entity.Users;

/*

注释(Annotation):在 javax.ws.rs.* 中定义,是 JAX-RS (JSR 311) 规范的一部分。

@Path:定义资源基 URI。由上下文根和主机名组成,资源标识符类似于 http://localhost:8080/RESTful/rest/hello。

@GET:这意味着以下方法可以响应 HTTP GET 方法。

@Produces:以纯文本方式定义响应内容 MIME 类型。

@Context: 使用该注释注入上下文对象,比如 Request、Response、UriInfo、ServletContext 等。

@Path(“{contact}”):这是 @Path 注释,与根路径 “/contacts” 结合形成子资源的 URI。

@PathParam(“contact”):该注释将参数注入方法参数的路径,在本例中就是联系人 id。其他可用的注释有 @FormParam、@QueryParam 等。

@Produces:响应支持多个 MIME 类型。在本例和上一个示例中,APPLICATION/XML 将是默认的 MIME 类型。

*/

/**

* function: CXF RESTful风格WebService

* @author hoojo

* @createDate 2012-7-20 下午01:23:04

* @file RESTSampleSource.java

* @package com.hoo.service

* @project CXFWebService

* @blog http://blog.csdn.net/IBM_hoojo

* @email hoojo_@126.com

* @version 1.0

*/

@Path(value = “/sample”)

public class RESTSampleSource implements RESTSample {

@Context

private UriInfo uriInfo;

@Context

private Request request;

@GET

@Produces(MediaType.TEXT_PLAIN)

public String doGet() {

return “this is get rest request”;

}

@GET

@Produces(MediaType.TEXT_PLAIN)

@Path(“/request/{param}”)

public String doRequest(@PathParam(“param”) String param,

@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse) {

System.out.println(servletRequest);

System.out.println(servletResponse);

System.out.println(servletRequest.getParameter(“param”));

System.out.println(servletRequest.getContentType());

System.out.println(servletResponse.getCharacterEncoding());

System.out.println(servletResponse.getContentType());

return “success”;

}

@GET

@Path(“/bean/{id}”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public User getBean(@PathParam(“id”) int id) {

System.out.println(“####getBean#####”);

System.out.println(“id:” + id);

System.out.println(“Method:” + request.getMethod());

System.out.println(“uri:” + uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());

User user = new User();

user.setId(id);

user.setName(“JojO”);

return user;

}

@GET

@Path(“/list”)

@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })

public Users getList() {

System.out.println(“####getList#####”);

System.out.println(“Method:” + request.getMethod());

System.out.println(“uri:” + uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());

List list = new ArrayList();

User user = null;

for (int i = 0; i < 4;i ++) {

user = new User();

user.setId(i);

user.setName(“JojO-” + i);

list.add(user);

}

Users users = new Users();

users.setUsers(list);

return users;

}

@GET

@Path(“/map”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public MapBean getMap() {

System.out.println(“####getMap#####”);

System.out.println(“Method:” + request.getMethod());

System.out.println(“uri:” + uriInfo.getPath());

System.out.println(uriInfo.getPathParameters());

Map<String, User> map = new HashMap<String, User>();

User user = null;

for (int i = 0; i < 4;i ++) {

user = new User();

user.setId(i);

user.setName(“JojO-” + i);

map.put(“key-” + i, user);

}

MapBean bean = new MapBean();

bean.setMap(map);

return bean;

}

/*

@Consumes:声明该方法使用 HTML FORM。

@FormParam:注入该方法的 HTML 属性确定的表单输入。

@Response.created(uri).build(): 构建新的 URI 用于新创建的联系人(/contacts/{id})并设置响应代码(201/created)。

您可以使用 http://localhost:8080/Jersey/rest/contacts/ 访问新联系人

*/

@POST

@Path(“/postData”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public User postData(User user) throws IOException {

System.out.println(user);

user.setName(“jojo##12321321”);

return user;

}

@PUT

@Path(“/putData/{id}”)

@Produces({ MediaType.APPLICATION_XML })

public User putData(@PathParam(“id”) int id, User user) {

System.out.println(“#####putData#####”);

System.out.println(user);

user.setId(id);

user.setAddress(“hoojo#gz”);

user.setEmail(“hoojo_@126.com”);

user.setName(“hoojo”);

System.out.println(user);

return user;

}

@DELETE

@Path(“/removeData/{id}”)

public void deleteData(@PathParam(“id”) int id) {

System.out.println(“#######deleteData#######” + id);

}

}

三、配置我们的WebService,修改applicationContext-server.xml。这里主要是添加jaxrs标签的支持,修改头部文件如下:

<?xml version\="1.0" encoding\="UTF-8"?\>

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:context\="http://www.springframework.org/schema/context"
xmlns:jaxws\="http://cxf.apache.org/jaxws"
**_xmlns:jaxrs\="http://cxf.apache.org/jaxrs"_**
xmlns:xsi\="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation\="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd
**_http://cxf.apache.org/jaxrs_**
**_http://cxf.apache.org/schemas/jaxrs.xsd_**"\>

特别注意上面加粗带下划线的部分,这是新增加的配置。我们发布restful WebService需要用到它。

然后在配置文件中添加如下配置

<import resource=“classpath:META-INF/cxf/cxf.xml”/>

<import resource=“classpath:META-INF/cxf/cxf-extension-soap.xml”/>

<import resource=“classpath:META-INF/cxf/cxf-servlet.xml”/>

<bean id=“restSample” class=“com.hoo.service.RESTSampleSource”/>

<jaxrs:server id=“restServiceContainer” address=“/rest”>

<jaxrs:serviceBeans\>
    <ref bean\="restSample" />
</jaxrs:serviceBeans\>
<jaxrs:extensionMappings\>
    <entry key\="json" value\="application/json" />
    <entry key\="xml" value\="application/xml" />
</jaxrs:extensionMappings\>
<jaxrs:languageMappings\>
       <entry key\="en" value\="en-gb"/>  
</jaxrs:languageMappings\>

</jaxrs:server>

这样服务器端就完成了CXF RESTful WebService的发布,启动你的tomcat。然后在浏览器中服务地址:http://localhost:8000/CXFWebService/ (其实这里请求的是CXFServlet,你可以看看上一篇Spring整合CXF文章的web.xml的配置)

你就可以看到我们这里刚刚发布的RESTSample rest的WebService

你也可以看看里面的xml,也就是WebService的wsdl文件内容。我们找一个GET方式的WebService的方法,在浏览器中调用一下试试

http://localhost:8000/CXFWebService/rest/sample/bean/123

这个url对应到下面这个方法

@GET

@Path(“/bean/{id}”)

@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })

public User getBean(@PathParam(“id”) int id)

结果如下

一篇xml文档内容。

四、编写客户端代码,调用RESTful WebService

package com.hoo.client;

import java.io.IOException;

import javax.ws.rs.core.MediaType;

import org.apache.cxf.jaxrs.client.WebClient;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hoo.entity.MapBean;

import com.hoo.entity.User;

import com.hoo.entity.Users;

import com.hoo.service.RESTSample;

/**

* function: RESTful风格WebService

* @author hoojo

* @createDate 2012-7-20 下午03:31:03

* @file RSETServiceClient.java

* @package com.hoo.client

* @project CXFWebService

* @blog http://blog.csdn.net/IBM_hoojo

* @email hoojo_@126.com

* @version 1.0

*/

public class RSETServiceClient {

private static WebClient client;
@Before
public void init() {
    // 手动创建webClient对象,注意这里的地址是发布的那个/rest地址
    //String url = "http://localhost:8000/CXFWebService/rest/";
    //client = WebClient.create(url);
    // 从Spring Ioc容器中拿webClient对象
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-client.xml");
    client = ctx.getBean("webClient", WebClient.class);
}
@After
public void destory(){
}
@Test
public void testGet() {
    System.out.println(client.path("sample").accept(MediaType.TEXT\_PLAIN).get(String.class));
总结一下

面试前要精心做好准备,简历上写的知识点和原理都需要准备好,项目上多想想难点和亮点,这是面试时能和别人不一样的地方。

还有就是表现出自己的谦虚好学,以及对于未来持续进阶的规划,企业招人更偏爱稳定的人。

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

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

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

相关文章

【蓝队小WIKI】攻防演练中防守方重点知识点整理

一、蓝队防守策略&#xff1a; 工作流程概述 Hvv蓝队技战法&#xff1a;Hvv蓝队技战法 - FreeBuf网络安全行业门户 3个阶段&#xff0c;4大要点&#xff0c;蓝队防守全流程纲要解读&#xff1a;攻防演练合集 | 3个阶段&#xff0c;4大要点&#xff0c;蓝队防守全流程纲要解读 -…

oracle 11g rac安装grid 执行root脚本add vip -n 。。。on node= ... failedFailed 错误处理

问题&#xff1a; CRS-4402: The CSS daemon was started in exclusive mode but found an active CSS daemon on node racdg1-1, number 1, and is terminating An active cluster was found during exclusive startup, restarting to join the cluster PRCN-2050 : The requ…

js小题:通过字符串执行同名变量怎么做

在JavaScript中&#xff0c;你不能直接使用一个字符串来直接引用一个变量&#xff0c;因为JavaScript是一种静态类型语言&#xff08;尽管它的类型在运行时可以变化&#xff09;&#xff0c;变量的名字在编译时就被确定了。但是&#xff0c;有几种方法可以实现类似的功能&#…

构建LangChain应用程序的示例代码:41、如何结合使用大型语言模型(LLMs)和 bash 进程来执行简单的文件系统命令指南

Bash 命令链使用指南 概述 本指南展示了如何结合使用大型语言模型&#xff08;LLMs&#xff09;和 bash 进程来执行简单的文件系统命令。 代码示例 from langchain_experimental.llm_bash.base import LLMBashChain from langchain_openai import OpenAI# 初始化 OpenAI 的…

k8s部署grafana beyla实现app应用服务依赖图可观测

k8s部署grafana beyla OS: Static hostname: test Icon name: computer-vm Chassis: vm Machine ID: 22349ac6f9ba406293d0541bcba7c05d Boot ID: 83bb7e5dbf27453c94ff9f1fe88d5f02 Virtualization: vmware Operating System: Ubuntu 22.04.4 LTS Kernel: Linux 5.15.0-105-g…

BEVM基于OP-Stack发布首个以WBTC为GAS连接以太坊和比特币生态的中继链

为了更好的连接以太坊和比特币生态&#xff0c;BEVM团队正在基于OPtimism的OP Stack来构建一个以WBTC为GAS兼容OP-Rollup的中继链&#xff0c;这条中继链将作为一种完全去中心化的中间层&#xff0c;把以太坊上的主流资产(WBTC/ ETH/USDC/USDT等)引入到BEVM网络。 不仅如此&am…

AlgorithmStar 度量 计算组件

AlgorithmStar 度量 计算组件 AlgorithmStar 本文将会基于 AlgorithmStar 1.40 以及以上的版本来演示&#xff0c;度量 计算 组件 的使用&#xff01; 目录 文章目录 AlgorithmStar 度量 计算组件目录获取到依赖库度量计算组件 计算实例距离计算代表 - 欧几里德距离计算组件…

Redis数据库(一):Redis数据库介绍与安装

Redis是一种高性能的开源内存数据库&#xff0c;支持多种数据结构&#xff08;如字符串、列表、集合等&#xff09;&#xff0c;具有快速的读写速度。它提供持久化、主从复制、高可用性和分布式部署等功能&#xff0c;适用于缓存、实时分析、消息队列等应用场景。Redis使用简单…

UE5 场景物体一键放入蓝图中

场景中&#xff0c;选择所有需要加入到蓝图的模型或物体。 点击 蓝图按钮&#xff0c;点击“将选项转换为蓝图” 在创建方法中&#xff0c;选择“子Actor”或着 “获取组件” 如果需要保持相对应的Actor的父子级别&#xff08;多层&#xff09;&#xff0c;那么选择“获取组件…

计算机组成原理 | 数据的表示、运算和校验(4)基本运算方法

补码加减&#xff08;运算与控制&#xff09; (-Y)补 [Y补]变补&#xff0c;这个要好好理解 (-Y)补&#xff1a;先将Y的符号位置反&#xff0c;在求-Y的补码&#xff08;数字为变反加1&#xff09; [Y补]变补&#xff1a;先求Y的补码&#xff08;数字为变反加1&#xff09;&…

protobuf实践+生成C++代码的解析

目录 1.实践1&#xff08;简单使用&#xff09; 2.实践2&#xff08;存储列表类数据&#xff09; 3.实践3&#xff08;定义RPC方法&#xff09; 4.解析protobuf的message类 5.解析protobuf的service类 6.Rpcchannel是什么呢&#xff1f; 1.实践1&#xff08;简单使用&…

Django中,update_or_create()

在Django中&#xff0c;可以使用update_or_create()方法来更新现有记录或创建新记录。该方法接受一个字典作为参数&#xff0c;用于指定要更新或创建的字段和对应的值。 update_or_create()方法的语法如下&#xff1a; 代码语言&#xff1a;python obj, created Model.obje…

python遍历文件夹中所有图片

python遍历文件夹中的图片-CSDN博客 这个是之前的版本&#xff0c;现在这个版本会更好&#xff0c;直接进来就在列表中 path glob.glob("1/*.jpg")print(path)print(len(path))path_img glob.glob("1/*.jpg")path_img.extend(path)print(len(path_img))…

问题解决:数据库自增id到最大报错

pgsql数据库id自增到长度问题&#xff1a; django.db.utils.DataError: nextval: reached maximum value of sequence "ip_prefix_info_id_seq" (32767) schema_name: ip_management_app table_name: ip_prefix_info # 先把自增id改到serial8&#xff0c;范围改大#…

行列视(RCV)在系统管理中的应用:解决生产型企业数据治理的挑战

行列视&#xff08;RCV&#xff09;作为一款面向生产型企业的综合性数据应用系统&#xff0c;在系统管理中扮演着至关重要的角色&#xff0c;特别是在解决生产型企业数据治理的挑战方面&#xff0c;表现出了卓越的性能。 首先&#xff0c;生产型企业面临着复杂而繁琐的数据治理…

学期结束如何发布期末成绩?

当期末的试卷最后一张被收起&#xff0c;当教室里的喧嚣逐渐沉寂&#xff0c;学生们的心中充满了对成绩的期待与忐忑。期末成绩&#xff0c;关乎着学生的心情&#xff0c;更关系到他们的未来学习动力。那么&#xff0c;如何在保护学生隐私的同时&#xff0c;高效地公布成绩呢&a…

vscode cmake debug 调试

在 VSCode 中调试使用 CMake 编译的程序&#xff0c;按照以下步骤进行&#xff1a; 1. **安装必要的扩展&#xff1a;** - 打开 VSCode&#xff0c;并确保你已经安装了以下扩展&#xff1a; - C/C&#xff08;由 Microsoft 提供&#xff09; - CMake - CMak…

Python Sqlalchemy基础使用

Python Sqlalchemy基础使用 Python Sqlalchemy基础使用基本使用创建Session创建ORM对象查询插入 进阶操作插入存在时更新执行SQL Python Sqlalchemy基础使用 这里记录一下&#xff0c;在编写python代码过程中使用Sqlalchemy的封装和基本使用方法。 (持续完善ing) 基本使用 …

代码随想录算法训练营Day48|188.买卖股票的最佳时机IV、309.最佳买卖股票时间含冷冻期、714.买卖股票的最佳时机含手续费

买卖股票的最佳时机IV . - 力扣&#xff08;LeetCode&#xff09; 至多可以购买k次&#xff0c;相比买卖股票的最佳时机III至多购买2次&#xff0c;区别在于次数不确定。 每买卖一次&#xff0c;dp数组的第二维度加2&#xff0c;dp数组的第二维度为2k1&#xff08;0-2k&…

TDengine 3.2.3.0 集成英特尔 AVX512!快来看看为你增添了哪些助力

在当今的 IoT 和智能制造领域&#xff0c;海量时序数据持续产生&#xff0c;对于这些数据的实时存储、高效查询和分析已经成为时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;的核心竞争力。作为一款高性能的时序数据库&#xff0c;TDengine 不仅采用…