代码“起作用”,因为它返回预期的信息(DemoPOJO对象列表)。但是,如下所示的控制台输出所示,正在对localhost上的REST服务进行两次调用:8080/v2/demopojo。我有一种感觉,第二次调用是对反应编程缺乏了解的结果,但我不知道第二次调用是在这个REST API上进行的,我想消除它,因为当部署“实际的东西”时,冗余很可能是一个性能问题。
在提供的代码中,在localhost:8080/v3/democlient(在DemoClientHandler中实现)上进行调用,然后使用WebClient对象访问localhost:8080/v2/demopojo(在DemoPOJOHandler中实现)上的相应REST服务。
(我已经将代码简化为仅与RESTendpoint/v3/democlient相关联的语句)
2019-09-26 12:30:23.389 INFO 4260 --- [ main] com.test.demo.DemoApplication : Starting DemoApplication on M7730-LFR with PID 4260 (D:\sandbox\DemoReactive\build\classes\java\main started by LesR in D:\sandbox\DemoReactive)
2019-09-26 12:30:23.391 INFO 4260 --- [ main] com.test.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-09-26 12:30:24.570 INFO 4260 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
2019-09-26 12:30:24.573 INFO 4260 --- [ main] com.test.demo.DemoApplication : Started DemoApplication in 1.41 seconds (JVM running for 1.975)
2019-09-26 12:30:28.796 INFO 4260 --- [ctor-http-nio-3] m.n.d.accesslogger.ServiceRequestLogger :
***** Begin, Access Request Log
Service request -> GET @ http://localhost:8080/v3/DemoClient
Service handled by -> com.test.demo.democlient.DemoClientHandler.getAll()
***** End, Access Request Log
2019-09-26 12:30:28.823 INFO 4260 --- [ctor-http-nio-8] m.n.d.accesslogger.ServiceRequestLogger :
***** Begin, Access Request Log
Service request -> GET @ http://localhost:8080/v2/DemoPOJO
Service handled by -> com.test.demo.demopojo.DemoPOJOHandler.getAll()
***** End, Access Request Log
2019-09-26 12:30:28.911 INFO 4260 --- [ctor-http-nio-9] m.n.d.accesslogger.ServiceRequestLogger :
***** Begin, Access Request Log
Service request -> GET @ http://localhost:8080/v2/DemoPOJO
Service handled by -> com.test.demo.demopojo.DemoPOJOHandler.getAll()
***** End, Access Request Log
@Component
public class DemoClientHandler {
public static final String PATH_VAR_ID = "id";
@Autowired
ServiceRequestLogger svcRequestLogger;
@Autowired
DemoClient demoClient;
public Mono<ServerResponse> getAll(ServerRequest request) {
Flux<DemoPOJO> fluxDemoPOJO = demoClient.getAll();
svcRequestLogger.logServiceRequest(this.getClass(), "getAll()", request);
return fluxDemoPOJO.hasElements().flatMap(hasElement -> {
return hasElement ? ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(fluxDemoPOJO, DemoPOJO.class)
: ServerResponse.noContent().build();
});
}
}
使用WebClient访问“第一级”REST API...
@Component
public class DemoClient {
private final WebClient client;
public DemoClient() {
client = WebClient.create();
}
public Flux<DemoPOJO> getAll() {
return client.get().uri("http://localhost:8080/v2/DemoPOJO")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.flatMapMany(response -> response.bodyToFlux(DemoPOJO.class));
}
)
“一级”处理程序...
@Component
public class DemoPOJOHandler {
@Autowired
private ServiceRequestLogger svcRequestLogger;
@Autowired
private DemoPOJOService service;
public Mono<ServerResponse> getAll(ServerRequest request) {
Flux<DemoPOJO> fluxDemoPOJO = service.getAll();
svcRequestLogger.logServiceRequest(this.getClass(), "getAll()", request);
return fluxDemoPOJO.hasElements().flatMap(hasElement -> {
return hasElement ? ServerResponse.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(fluxDemoPOJO, DemoPOJO.class)
: ServerResponse.noContent().build();
});
}
}
用于第二级(WebClient)REST API的路由器...
@Configuration
public class DemoClientRouter {
@Bean
public RouterFunction<ServerResponse> clientRoutes(DemoClientHandler requestHandler) {
return nest(path("/v3"),
nest(accept(APPLICATION_JSON),
RouterFunctions.route(RequestPredicates.GET("/DemoClient"), requestHandler::getAll)));
}
}
@Configuration
public class DemoPOJORouter {
@Bean
public RouterFunction<ServerResponse> demoPOJORoute(DemoPOJOHandler requestHandler) {
return nest(path("/v2"),
nest(accept(APPLICATION_JSON),
RouterFunctions.route(RequestPredicates.GET("/DemoPOJO"), requestHandler::getAll)));
}
}
@Component
public class DemoPOJOService {
@Autowired
private DemoPOJORepo demoPOJORepo;
public Flux<DemoPOJO> getAll() {
return Flux.fromArray(demoPOJORepo.getAll());
}
}
@Component
public class DemoPOJORepo {
private static final int NUM_OBJS = 5;
private static DemoPOJORepo demoRepo = null;
private Map<Integer, DemoPOJO> demoPOJOMap;
private DemoPOJORepo() {
initMap();
}
public static DemoPOJORepo getInstance() {
if (demoRepo == null) {
demoRepo = new DemoPOJORepo();
}
return demoRepo;
}
public DemoPOJO[] getAll() {
return demoPOJOMap.values().toArray(new DemoPOJO[demoPOJOMap.size()]);
}
private void initMap() {
demoPOJOMap = new TreeMap<Integer, DemoPOJO>();
for (int ndx = 1; ndx < (NUM_OBJS + 1); ndx++) {
demoPOJOMap.put(ndx, new DemoPOJO(ndx, "foo_" + ndx, ndx + 100));
}
}
}
日志(SLF4J/(logback*)客户端对应用程序日志的REST服务访问...
@Component
public class ServiceRequestLogger {
Logger logger = LoggerFactory.getLogger(this.getClass());
public void logServiceRequest(Class serviceHandler, String serviceMethod, ServerRequest request) {
logger.info(buildLogMessage(serviceHandler, serviceMethod, request));
}
private String buildLogMessage(Class serviceHandler, String serviceMethod, ServerRequest request) {
StringBuilder logMessage = new StringBuilder();
/* <housekeeping code to build message to log */
return logMessage.toString();
}
}
这是第二次尝试,通过修改的演示代码,希望能更好地说明这个问题。代码已经被剥离,除去了所有的元素,除了那些演示正在遇到的问题的元素。 添加注意:一些额外的测试做了,结果张贴作为一个答案(副扩展这篇文章)。这可能是“预期的行为”,但我仍在努力理解“为什么”。 代码“起作用”,因为它返回预期的信息(字符串或字符串列表)。但是,当使用WebClient访问返回流量的RESTendpoint(localho
本文向大家介绍请问tcp握手为什么两次不可以?为什么不用四次?相关面试题,主要包含被问及请问tcp握手为什么两次不可以?为什么不用四次?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 两次不可以:tcp是全双工通信,两次握手只能确定单向数据链路是可以通信的,并不能保证反向的通信正常 不用四次: 本来握手应该和挥手一样都是需要确认两个方向都能联通的,本来模型应该是: 1.客户端发送syn0给
本小节会创建我们的第一个 Django 工程以及第一个应用,接下来的所有示例将会在这个工程基础上进行演示。 1. 创建第一个Django应用程序 在创建第一个 Django 应用程序之前,我们需要使用 pyenv 工具创建相应的虚拟环境,操作如下: 新建一个统一的目录,用于存放 Django 工程代码: [root@server ~]# mkdir django-manual [root@serv
我写简单的脚本使用诱变库,其中计数文件夹中的音频文件量和文件夹的整个音频播放时间(包括子文件夹的音频文件)。 经过一些测试,我发现我的脚本访问了一些文件夹两次。通常这些目录是另一个子文件夹中的子文件夹。结果它打印了这样的结果: 但实际上,如果将所有音频曲目移动到一个文件夹中,并在该测试文件夹上运行脚本,则会显示不同的结果: 实际上,测试文件夹中的音频曲目数量是885。我用命令检查了它,那么为什么o
问题内容: 是否有一个(独立的!)Java API,它将XML- RPC接口包装到bugzilla?我不想为此编写自己的api,而且我实际上找不到能够做到这一点(而且只能做到这一点)的库。 更新: 我正在寻找 只用Java编写的类似http://oss.dbc.dk/bugzproxy/的东西 问题答案: 我知道这是一个有点老的话题,但是有相同问题的人很可能会在这里落下来。我想分享一篇博客文章,我
问题内容: 我有一个简单的AJAX表单,该表单可以在提交时正常运行。但是,如果我随后将新数据输入相同的表单(而不刷新页面),则它将提交两次表单。如果我第三次这样做,那么它将第三次提交表单,依此类推。为什么这样做呢?这是我的代码: 问题答案: 即使我在开发AJAX登录表单时也遇到了同样的问题。搜寻了几个小时后,我找到了解决方案。希望这对您有所帮助。 基本上,您必须在ajax请求完成后 取消绑定 表单