我使用 ErrorDecoder 返回正确的异常而不是 500 状态代码。
有没有办法在解码器中检索原始消息。我可以看到它在 FeignException 中,但不在 decode 方法中。我所拥有的只是“状态代码”和一个空的“原因”。
public class CustomErrorDecoder implements ErrorDecoder {
private final ErrorDecoder errorDecoder = new Default();
@Override
public Exception decode(String s, Response response) {
switch (response.status()) {
case 404:
return new FileNotFoundException("File no found");
case 403:
return new ForbiddenAccessException("Forbidden access");
}
return errorDecoder.decode(s, response);
}
}
Run Code Online (Sandbox Code Playgroud)
这里的原始消息:“消息”:“禁止访问文件”
feign.FeignException: status 403 reading ProxyMicroserviceFiles#getUserRoot(); content:
{"timestamp":"2018-11-28T17:34:05.235+0000","status":403,"error":"Forbidden","message":"Access to the file forbidden","path":"/root"}
Run Code Online (Sandbox Code Playgroud)
此外,我像 RestController 一样使用我的 FeignClient 接口,所以我不使用任何其他填充有可以封装方法调用的代理的 Controler。
@RestController
@FeignClient(name = "zuul-server")
@RibbonClient(name = "microservice-files")
public interface …Run Code Online (Sandbox Code Playgroud) 嗨,试图实现的是获取从前端提交的承载令牌在 java spring boot RESTApi 控制器中,并使用伪装客户端向另一个微服务发出另一个请求?这是我所做的
上图是我如何处理邮递员的请求,这是我的控制器代码:
@Operation(summary = "Save new")
@PostMapping("/store")
public ResponseEntity<ResponseRequest<TransDeliveryPlanning>> saveNewTransDeliveryPlanning(
@Valid @RequestBody InputRequest<TransDeliveryPlanningDto> request) {
TransDeliveryPlanning newTransDeliveryPlanning = transDeliveryPlanningService.save(request);
ResponseRequest<TransDeliveryPlanning> response = new ResponseRequest<TransDeliveryPlanning>();
if (newTransDeliveryPlanning != null) {
response.setMessage(PESAN_SIMPAN_BERHASIL);
response.setData(newTransDeliveryPlanning);
} else {
response.setMessage(PESAN_SIMPAN_GAGAL);
}
return ResponseEntity.ok(response);
}
Run Code Online (Sandbox Code Playgroud)
这是我的服务的样子:
public TransDeliveryPlanning save(InputRequest<TransDeliveryPlanningDto> request) {
Future<List<PartnerDto>> initPartners = execs.submit(getDataFromAccount(transDeliveryPlanningDtSoDtoPartnerIdsSets));
}
public Callable<List<PartnerDto>> getDataFromAccount(Set<Long> ids) {
String tokenString = "i should get the token from postman, how do i get it to here?";
List<PartnerDto> partnerDtoResponse = …Run Code Online (Sandbox Code Playgroud) 我遇到了麻烦!正如我一直在阅读的那样,这种情况的发生是因为它不再被接受。但我该如何解决呢?这是我一直在尝试映射的代码。
@FeignClient(name = "product-service")
@RequestMapping("api/products/")
public interface ProductClient {
@GetMapping("/{id}")
ResponseEntity<Product> getProduct(@PathVariable("id") Long id);
@GetMapping("/{id}/stock")
ResponseEntity<Product> updateStockProduct(@PathVariable("id") Long id,@RequestParam(name = "quantity", required = true) Integer quantity);
}
Run Code Online (Sandbox Code Playgroud)
预先感谢您的任何建议或解决方案!
我快速浏览了Feign的源代码,我发现Feign使用JDK HttpUrlConnection发出HTTP请求,并在请求完成时关闭它而不使用连接池.我怀疑这种方式的效率.然后我读了Spring的文档,RestTemplate它说RestTemplate可以切换到Apache Http Client或OKHttp来发送HTTP请求:
注意:默认情况下,RestTemplate依赖于标准JDK工具来建立HTTP连接.您可以通过HttpAccessor.setRequestFactory(org.springframework.http.client.ClientHttpRequestFactory)属性切换到使用不同的HTTP库,例如Apache HttpComponents,Netty和OkHttp.
这是否意味着RestTemplate在性能方面优于Feign?
我正在尝试从 Feign 客户端应用程序调用一些由 client_credentials 授权类型保护的后端系统。
可以使用以下 curl 结构检索来自后端系统的访问令牌(仅作为示例):
curl --location --request POST '[SERVER URL]/oauth/grant' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Cookie: WebSessionID=172.22.72.1.1558614080219404; b8d49fdc74b7190aacd4ac9b22e85db8=2f0e4c4dbf6d4269fd3349f61c151223' \
--data-raw 'grant_type=client_credentials' \
--data-raw 'client_id=[CLIENT_ID]' \
--data-raw 'client_secret=[CLIENT_SECRET]'
{"accessToken":"V29C90D1917528E9C29795EF52EC2462D091F9DC106FAFD829D0FA537B78147E20","tokenType":"Bearer","expiresSeconds":7200}
Run Code Online (Sandbox Code Playgroud)
然后应将此 accessToken 设置在标头中,以用于对后端系统的后续业务调用。
所以现在我的问题是,如何使用 Feign 和 Spring Boot Security 5 来实现这一点。 经过一些研究,我找到了这个解决方案(不起作用):
spring:
security:
oauth2:
client:
registration:
backend:
client-id:[CLIENT_ID]
client-secret: [CLIENT_SECRET]
authorization-grant-type: client_credentials
provider:
backend:
token-uri: [SERVER URL]/oauth/grant
Run Code Online (Sandbox Code Playgroud)
curl --location --request POST '[SERVER URL]/oauth/grant' \
--header 'Content-Type: application/x-www-form-urlencoded' …Run Code Online (Sandbox Code Playgroud) 我正在尝试运行该应用程序,但不断提示此错误。
描述:
com.clientui.clientui.controller.ClientController 中构造函数的参数 0 需要类型为“org.springframework.cloud.openfeign.FeignContext”的 bean,但无法找到。
行动:
考虑在配置中定义“org.springframework.cloud.openfeign.FeignContext”类型的 bean。
这是代码:
主要的
package com.clientui.clientui;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
@EnableFeignClients("com.clientui")
public class ClientuiApplication {
public static void main(String[] args) {
SpringApplication.run(ClientuiApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
控制器
package com.clientui.clientui.controller;
import com.clientui.clientui.beans.ProductBean;
import com.clientui.clientui.proxies.MicroserviceProduitsProxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class ClientController {
private final MicroserviceProduitsProxy produitsProxy;
public ClientController(MicroserviceProduitsProxy produitsProxy){
this.produitsProxy = produitsProxy;
}
@RequestMapping("/") …Run Code Online (Sandbox Code Playgroud) 我有一些 fiegn 客户端发送请求其他微服务。
@FeignClient(name="userservice")
public interface UserClient {
@RequestMapping(
method= RequestMethod.GET,
path = "/userlist")
String getUserByid(@RequestParam(value ="id") String id);
}
Run Code Online (Sandbox Code Playgroud)
现在我正在发送这样的请求
try {
String responseData = userClient.getUserByid(id);
return responseData;
}
catch(FeignException e)
{
logger.error("Failed to get user", id);
}
catch (Exception e)
{
logger.error("Failed to get user", id);
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是,如果发生任何 FeignException,我不会收到任何错误代码。
我需要在其他 APIS 中发送相应的错误代码以发送给调用方
那么如何提取错误代码呢?我想提取错误代码并构建一个 responseEntity
我得到了这段代码,但不知道如何在我的函数中使用。
我正在尝试编写一个访问公共 REST API 的程序。为了让我能够使用它,我需要提供 OAuth2 令牌。
我的应用程序使用 Spring Boot 2.4.2 和 Spring Cloud 版本 2020.0.1。应用程序本身每 24 小时调用一次 REST API,下载数据并将其存储在数据库中。不同的微服务在其他时间点使用这些数据,并且需要每天刷新数据。
我的方法是使用 OpenFeign 声明使用 REST API 的 REST 客户端并为其提供 OAuth2 令牌。这是一个非常常见的问题,因此我认为机器对机器的client_credentials工作流程已有详细记录。
事实上,我确实找到了一个使用 OpenFeign 执行此操作的简单示例 - 这里: https: //github.com/netshoes/sample-feign-oauth2-interceptor/blob/master/src/main/java/com/sample/feign /oauth2/interceptor/OrderFeignClientConfiguration.java
TL;DR:尝试编写需要 OAuth2 令牌(client_credentials 授予类型)的机器对机器微服务。
这是我的第一次尝试,但不幸的是,随着新的 Spring Security 版本的出现,我似乎无法实例化OAuth2FeignRequestInterceptor,我可能遇到了包问题。然后我继续研究 Spring Security 的文档和新的 OAuth2 重写,可以在这里找到:https ://docs.spring.io/spring-security/site/docs/5.1.2.RELEASE/reference/htmlsingle /#oauth2client .
我的方法是通过RequestInterceptor添加 Authorization Bearer 标头,将当前的 OAuth2 令牌注入 OpenFeign 客户端的请求中。我的假设是,我可以使用 Spring Security OAuth2 层或多或少自动地检索此信息。
使用文档,我尝试OAuth2RegisteredClient为我的拦截器提供一个 bean …
我正在使用 spring-cloud 的 feignClient 并且当我的界面中有多个 Beans 参数时出现问题,错误显示如下:
Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.wxl.pros.test.web.common.CommonResObject com.wxl.pros.test.web.feign.OrderFeignClient.createOrder(com.wxl.pros.test.services.form.order.CreateOrderForm,com.wxl.pros.test.services.vo.User)
at feign.Util.checkState(Util.java:128)
at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:114)
at org.springframework.cloud.netflix.feign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:133)
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64)
at feign.hystrix.HystrixDelegatingContract.parseAndValidatateMetadata(HystrixDelegatingContract.java:34)
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146)
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53)
at feign.Feign$Builder.target(Feign.java:209)
at org.springframework.cloud.netflix.feign.HystrixTargeter.target(HystrixTargeter.java:48)
at org.springframework.cloud.netflix.feign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:184)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
... 27 common frames omitted
Run Code Online (Sandbox Code Playgroud)
这是我的接口方法之一:
@RequestMapping(value="/order/createOrder",method=RequestMethod.POST)
public CommonResObject createOrder(@RequestBody OrderForm orderForm,@RequestBody User user);
Run Code Online (Sandbox Code Playgroud) 我用Spring Boot创建了一个简单的Feign Client:
@FeignClient("spring-cloud-eureka-client")
public interface GreetingClient {
@RequestMapping("/greeting")
String greeting(@RequestParam String name);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试启动一个应用程序时,我收到一个错误:
java.lang.IllegalStateException: RequestParam.value() was empty on parameter 0
Run Code Online (Sandbox Code Playgroud)
首先,我不明白是什么原因和谷歌搜索,但没有找到答案.几乎不可思议地我发现如果明确地写请求参数名称它是有效的:
@RequestParam("name") String name
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:它是一个错误还是可以配置为不明确写入请求参数名称?
spring-boot ×3
spring-cloud ×3
spring ×2
bearer-token ×1
exception ×1
feign ×1
java ×1
oauth ×1