我正尝试使用Httpmethod为POST的Spring Boot应用程序中经过认证的其余Web服务,
下面,我想展示所有设置如何工作以使用HttpMethod.GET的身份验证的Web服务,然后进行哪些更改以尝试使用HttpMethod.POST的相同身份验证的Web服务并抛出401未经授权的错误,
RestTemplateFactory获取restTemplte,
public class RestTemplateFactory implements FactoryBean<RestTemplate>, InitializingBean {
@Autowired
private RestTemplate restTemplate;
public RestTemplate getObject() {
return restTemplate;
}
public Class<RestTemplate> getObjectType() {
return RestTemplate.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() {
HttpHost host = new HttpHost("localhost", 9090, "http");
restTemplate = new RestTemplate(
new HttpComponentsClientHttpRequestFactoryBasicAuth(host));
}
}
对于基本身份验证,
public class HttpComponentsClientHttpRequestFactoryBasicAuth extends HttpComponentsClientHttpRequestFactory {
HttpHost host;
public HttpComponentsClientHttpRequestFactoryBasicAuth(HttpHost host) {
super();
this.host = host;
}
protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) {
return createHttpContext();
}
private HttpContext createHttpContext() {
AuthCache authCache = new BasicAuthCache();
BasicScheme basicAuth = new BasicScheme();
authCache.put(host, basicAuth);
BasicHttpContext localcontext = new BasicHttpContext();
localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
return localcontext;
}
}
为HttpMethod.Get方法调用经过身份验证的Web服务,
public ResponseEntity<SomeResponse> consumeRestApi(SomeRequest request) throws InvalidDataException {
ResponseEntity<SomeResponse> responseEntity = null;
try {
RestTemplate restTemplate = restTemplateFactory.getRestTemplate();
restTemplate
.getInterceptors()
.add(new BasicAuthorizationInterceptor(username, pwd));
responseEntity = restTemplate.exchange("http://localhost:9090/sendMail?phone=60598745&email=abc@gmail.com", HttpMethod.GET, null, SomeResponse.class);
} catch (Exception e) {
// Exception handing...
}
return responseEntity;
}
我确实在虚拟机上使用HttpMethod.Get在本地主机上运行,这是我在上述设置中尝试使用的经过身份验证的服务,
@RequestMapping(value = "/sendMail", method = RequestMethod.GET)
public ResponseEntity<SomeResponse> sendmail(@RequestParam String phone, @RequestParam String email){
SomeResponse response = SomeResponse.builder()
.id("101")
.type("formdata")
.fieldValues(getFieldValues(phone,email))
.build();
return new ResponseEntity<>(response,HttpStatus.CREATED);
}
当使用HttpMethod.GET方法时,它可以很好地完成上述所有设置,
现在,我想更改要使用的同一Web服务,以接受HttpMethod.POST
下面是我尝试的更改,但它会返回401错误,即未经授权的错误
我尝试发布方法的更改
通过保持RestTemplateFactory
和HttpComponentsClientHttpRequestFactoryBasicAuth
相同
我首先更改,虚拟服务器上的其余api接受POST的请求,
@RequestMapping(value = "/sendMail", method = RequestMethod.POST)
public ResponseEntity<SomeResponse> sendmail(@RequestParam String phone, @RequestParam String email){
// Same as above
}
下一个更改是使用方法post调用方法
public ResponseEntity<SomeResponse> consumeRestApi(SomeRequest request) throws InvalidDataException {
ResponseEntity<SomeResponse> responseEntity = null;
try {
RestTemplate restTemplate = restTemplateFactory.getRestTemplate();
restTemplate
.getInterceptors()
.add(new BasicAuthorizationInterceptor(username, pwd));
SomeResponse response = restTemplate.postForObject("http://localhost:9090/sendMail?phone=60598745&email=abc@gmail.com",request, SomeResponse.class);
} catch (Exception e) {
// Exception handling....
}
}
return new ResponseEntity<SomeResponse>(HttpStatus.CREATED);
}
有人对我的错有什么建议吗? 提前致谢。
答案 0 :(得分:1)
我想问题在于您创建和配置RestTemplate
的方式。 Spring Boot提供了RestTemplateBuilder
来构建RestTemplate
,并且它具有生成器方法来进行其他配置。
此外,RestTemplate
是线程安全的,因此可以重新使用创建的实例,而不必重新创建它以使用它。话虽这么说,您的调用类可以重构为这样的东西
public class EndpointTester {
private final RestTemplate rest;
public EndpointTester(RestTemplateBuilder rtb, String username, String pwd) {
this.rest = rtb.basicAuthorization(username, pwd).build();
}
public ResponseEntity<SomeResponse> consumeRestApi(SomeRequest request) throws InvalidDataException {
ResponseEntity<SomeResponse> responseEntity = null;
try {
responseEntity = rest.postForEntity("http://localhost:9090/sendMail?phone=60598745&email=abc@gmail.com", null, SomeResponse.class);
} catch (Exception e) {
// Exception handing...
}
return responseEntity;
}
}
这样,您就不需要RestTemplateFactory
和HttpComponentsClientHttpRequestFactoryBasicAuth
了,从而简化了配置和代码。