【发布时间】:2021-04-22 20:36:14
【问题描述】:
我需要使用 feign 发出 API 请求。方法类型:POST;标头必须包含Content-Type = text/xml。
我的代码:
@Component
@ConfigurationProperties("client.machine")
class MachineProperties {
lateinit var url: String
lateinit var timeout: String
}
@Configuration
class MachineClientConfig(
private val connectionProperties: MachineProperties,
private val meterRegistry: MeterRegistry,
private val objectMapper: ObjectMapper
) {
@Bean
fun machineApi() = Feign.builder()
.addCapability(MicrometerCapability(meterRegistry))
.retryer(DefaultEtsmIntegratonRetryer())
.encoder(JacksonEncoder(objectMapper))
.decoder(JacksonDecoder(objectMapper))
.decode404()
.logger(Slf4jLogger(MachineApi::class.java))
.options(Request.Options(connectionProperties.timeout.toInt(), connectionProperties.timeout.toInt()))
.target(MachineApi::class.java, connectionProperties.url)!!
}
@Headers(
HttpHeaders.ACCEPT + ": " + MediaType.TEXT_XML_VALUE,
HttpHeaders.CONTENT_TYPE + ": " + MediaType.TEXT_XML_VALUE
)
interface MachineApi {
@RequestLine("POST /api/v1/charge")
fun sendRequest(body: String): MachineResponse
}
@Service
class MachineClient(private val machineApi: MachineApi) {
fun sendRequest(body: String, dealId: Long): MachineResponse {
return machineApi.sendRequest(body)
}
}
public class JacksonEncoder implements Encoder {
private final ObjectMapper mapper;
public JacksonEncoder() {
this(Collections.<Module>emptyList());
}
public JacksonEncoder(Iterable<Module> modules) {
this(new ObjectMapper()
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.configure(SerializationFeature.INDENT_OUTPUT, true)
.registerModules(modules));
}
public JacksonEncoder(ObjectMapper mapper) {
this.mapper = mapper;
}
@Override
public void encode(Object object, Type bodyType, RequestTemplate template) {
try {
JavaType javaType = mapper.getTypeFactory().constructType(bodyType);
template.body(mapper.writerFor(javaType).writeValueAsBytes(object), Util.UTF_8);
} catch (JsonProcessingException e) {
throw new EncodeException(e.getMessage(), e);
}
}
}
当我从 MachineClient 类调用 sendRequest 方法时,我收到如下错误:
feign.FeignException$Forbidden: [403 Forbidden] during [POST] to [https://dev.ed.com/tsm/v1/charge] [MachineApi#sendRequest(String)]: [{
"httpCode": "403",
"moreInformation": "SQL-Injection Error"
}]
但是当我尝试通过 curl 拨打电话时效果很好。
curl --location --request POST 'https://dev.ed.com/tsm/v1/charge' \
--header 'Content-Type: text/xml' \
--data-raw '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ChargeRq>...</ChargeRq>'
我的代码中缺少什么以及为什么会出现错误?请帮忙,我没有更多的想法
【问题讨论】:
-
body变量的值是多少?您可以打印和检查。另外,我看到content-type丢失了,它出现在 curl 请求中 -
@sidgate
body是由Marshaller从JAXBContext(javax.xml.bind) 生成的xml 字符串。生成后,我在控制台中打印这个xml,并在通过curl检查时使用它(我只是从控制台复制并粘贴到Postman中)。 -
@sidgate 我试图发送一个空字符串
"",得到了同样的错误。然后我不明白为什么没有发送值:-(
标签: rest kotlin http-status-code-403 feign