I am trying to hide my API Key and therefore am setting up my Retrofit Api Interface as such:
public interface ApiInterface {
#GET("?api_key=" + popularmovies.name.com.popularmovies.BuildConfig.TMD_API_KEY + "&language=en-US")
Call<Movies> getImages();
}
However, I am receiving an error "Attribute value must be a constant." Is there a way to resolve and access this String?
UPDATE: Here is a second try:
private static final String API_KEY = popularmovies.troychuinard.com.popularmovies.BuildConfig.TMD_API_KEY;
public interface ApiInterface {
#GET("?language=en-US")
Call<Movies> getImages(#Query("api_key") API_KEY);
}
UPDATE: Here is a third try:
Below is the logging I am seeing as the URL making the request, as can be seen the API Key is now at the end of the URL which is incorrect syntax:
06-10 18:41:33.212 4969-4993/? D/OkHttp: <-- 401 Unauthorized http://api.themoviedb.org/3/movie/popular?language=en-US&api_key=?api_key%3D09b0a9a9d5d9ddee2b3bc69e78b02457 (592ms)
Access-Control-Allow-Origin: *
Use:
#GET("/rest/of/your/path/here?language=en-US")
Call<Movies> getImages(#Query("api_key") apiKey);
where you pass in popularmovies.name.com.popularmovies.BuildConfig.TMD_API_KEY to getImages():
Call<Movies> call=yourRetrofitInterface.getImages(BuildConfig.TMD_API_KEY);
Also, your #GET annotation seems to be missing the path to the REST endpoint (shown in my sample as /rest/of/your/path/here).
Related
I am trying to access the POST API from my spring app to angular but little bit confused how to use and access the given API in my angular app.
Spring REST API
#RequestMapping(value = "/getWelcomeMessage", method = RequestMethod.POST)
public String getLoginWelcomeMessage() {
return details.getLoginWelcomeMessage();
}
The given API is fetching the welcome message details from my oracle DB and returning a string value. I am trying to access the given REST API in my angular code through services. I had define the post service as follows
export class LoginService {
constructor(private http : HttpClient) { }
welcomeMessageService(){
const headers = {'content-type':'application/text'}
return this.http.put("http://localhost:8080/API/getWelcomeMessage",null,
{'headers':headers});
}
}
As the post method requires three arguments URL, Body and header. But in my case my spring REST API doesn't contain any body and returning a string. So, I had define the body as null and change the header type to text as it is JASON by default.
At last, I am trying to access the given service method by injecting it in my component as follows-
export class LoginComponent implements OnInit {
message:string;
constructor(private loginService : LoginService) { }
ngOnInit(): void {
this.loginService.welcomeMessageService().subscribe(
response =>{
console.log(response);
this.message = response;
}
)
}
}
But when I am trying to assign the response to the string I am getting the error that string cannot be assigned to the object. I am little bit confused why this error is occurring as I had also changed the header type to string while defining my service but still getting the error.
It can be a great help if anybody guide me regarding this as I am new to angular and little bit confused with integration part of API with angular.
Use { responseType: 'text' } and also send an empty body not null
export class LoginService {
constructor(private http : HttpClient) { }
welcomeMessageService(){
return this.http.put("http://localhost:8080/API/getWelcomeMessage",{},
{ responseType: 'text' });
}
}
Maybe you have copied the function wrong but check also here
#RequestMapping(value = "/getWelcomeMessage", method = RequestMethod.POST)
public String getLoginWelcomeMessage() {
return details.getLoginWelcomeMessage();
}
This is a Post method not a put that you are trying to call
As for cors error add the following to the backend just above #Controller or #RestControler whatever you have
#CrossOrigin(value = {"http://localhost:4200"}, methods = {GET,POST,PUT,DELETE})
I have been trying to set a webhook for the person.updated API from Stripe. I am trying a test webhook where I send a String in the method, like this:
#ApiOperation(value = "Webhook controller")
#PostMapping("/accountUpdate")
public void handle(#RequestBody String event1, Response response, HttpServletRequest httpServletRequest){
}
and then in my Webhook.constructEvent, I am passing that String event1 as follows:
try {
event = Webhook.constructEvent(
event1, sigHeader, endpointSecret
);
}
But I am getting an error saying: No signatures found matching the expected signature for payload
I have tried to parse the String event1 (Which is the request body) into Json and it doesn't work. Passing the Request object instead of String didn't work either.
It seems like your end point Secret which you are providing in your code is incorrect or not matching to your person.update webhook's secret. End point secret goes like this.
"secret": "whsec_gaasdfkalkkklasew**********"
I have an authorization server [Simple Class annotated with #SpringBootApplication,
#RestController,#Configuration,#EnableAuthorizationServer & oauth2 security] running on port 8081 which works fine & provides the access token when requested from POSTMAN using POST method along with needful parameters in the form of key value pair,
http://localhost:8080/oauth/token, but how should i implement the camel route in java to get the access token by passing parameters in body ?
This question is more about sending multipart/form-data with Apache Camel. I was playing with it some time ago and solved it with custom Processor, converting headers to multipart/form-data format with Content-Disposition: form-data.
This is my Processor converting headers to multipart/form-data format:
public class PrepareMultipartFormData implements Processor {
private String[] multipartHeaders;
public PrepareMultipartFormData(String... multipartHeaders) {
this.multipartHeaders = multipartHeaders;
}
#Override
public void process(Exchange exchange) throws Exception {
addMultipart(exchange.getIn(), multipartHeaders);
}
private static void addMultipart(Message message, String... multipartKeys){
final String boundary = "---------------------------"+RandomStringUtils.randomAlphanumeric(9);
message.setHeader(Exchange.CONTENT_TYPE, "multipart/form-data;boundary="+boundary);
StringBuilder sb = new StringBuilder("--").append(boundary);
for (String key: multipartKeys) {
sb.append("\r\n")
.append("Content-Disposition: form-data; name=\"").append(key).append("\"")
.append("\r\n\r\n")
.append(message.getHeader(key, String.class))
.append("\r\n")
.append("--").append(boundary);
}
message.setBody(sb.toString());
}
}
To OAuth request token you need to send:
HTTP headers
Authorization header - This is part of standard HTTP component specified by endpoint options authUsername and authPassword
Content-Type - This is added in my PrepareMultipartFormData Processor
Form data - These are converted from headers in PrepareMultipartFormData Processor
grant_type
username
password
client_id
Final route can be implemented in this way:
(Replace constants with some expressions, to set it dynamically. If you need only token in response, add some unmarshalling, since this route returns JSON)
from("direct:getTokenResponse")
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.HTTP_PATH, constant("oauth/token"))
.setHeader("grant_type", constant("password"))
.setHeader("username", constant("admin"))
.setHeader("password", constant("admin1234"))
.setHeader("client_id", constant("spring-security-oauth2-read-write-client"))
.process(new PrepareMultipartFormData("grant_type", "username", "password", "client_id"))
.to("http://localhost:8080?authMethod=Basic&authUsername=oauth-endpoint-username&authPassword=oauth-endpoint-password")
.convertBodyTo(String.class)
.to("log:response");
Updating answer to provide a bit shorter implementation of PrepareMultipartFormData#addMultipart using MultipartEntityBuilder.
private static void addMultipart(Message message, String... multipartKeys) throws Exception{
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
for (String key: multipartKeys) {
builder.addTextBody(key, message.getHeader(key, String.class));
}
HttpEntity resultEntity = builder.build();
message.setHeader(Exchange.CONTENT_TYPE, resultEntity.getContentType().getValue());
message.setBody(resultEntity.getContent());
}
I'm trying to retrieve a OAUTH2 token from our IDM server - I've tried several flavors of rudimentary examples, but all of them return a 200 status with no code included. I can do it with no trouble via postman, using a header of:
Content-Type application/x-www-form-urlencoded
... and sending the client_id, redirect_uri and code parameters. I get something back that looks like this:
{
"access_token": "abcd...",
"token_type": "bearer",
"expires_in": 3600
}
Here's the super rudimentary code intended to do no more than see if I can grab the token (at this point):
public class Service {
public String getToken() {
String client_id = "f2e8...";
String redirect_uri = "https://mysite/";
String code = "AAAAAA...";
form = new Form();
form.param("client_id", client_id);
form.param("code", code);
form.param("redirect_uri", redirect_uri);
JerseyClientBuilder jerseyClientBuilder = new JerseyClientBuilder();
JerseyWebTarget jerseyWebTarget =
jerseyClientBuilder.build().target("https://token-source-site/");
Response response = jerseyWebTarget.request().post(Entity.form(form));
return response.toString();
}
}
But all I get back is:
InboundJaxrsResponse{context=ClientResponse{method=POST,
uri=https://token-source-site/, status=200, reason=OK}}
Any thoughts on what Postman might be doing that my code isn't?
It's not going to show to the response body when you just call toString() on the Response. You need to extract the body from it by calling Response#readEntity.
But even trying to extract it to a String, you have the problem of still having to parse the string. Best thing to do is to create a POJO for the token response
public class AccessTokenResponse {
#JsonProperty("access_token")
private String accessToken;
#JsonProperty("token_type")
private String tokenType;
#JsonProperty("expires_in")
private long expiresIn;
// getters and setters
}
Then you can do
Response response = jerseyWebTarget.request().post(Entity.form(form));
return response.readEntity(AccessTokenResponse.class);
Make the method return AccessTokenResponse, so the client has access to the other properties also.
For this to work, you will need to have the Jackson provider dependency
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
I am using Retrofit below 2.0 in order to make API call.
The endpoint is "http://api.themoviedb.org/3".
The method is
#GET("/discover/movie")
void getMovies(Callback<MoviesResponse> callback);
They want me to add api_key as parameter. You can see the instructions here.
I am creating interceptor and setting it while building the client.
This is the overridden method of the interceptor.
#Override
public void intercept(RequestFacade request) {
request.addHeader("api_key", MY_API_KEY);
}
For some reason I get Unauthorized error.
"Invalid API key: You must be granted a valid key."
The example they are giving is:
http://api.themoviedb.org/3/movie/550?api_key=###
I found what was wrong. I was adding a header while they were asking for parameter.
#Override
public void intercept(RequestFacade request) {
request.addQueryParam(HEADER_NAME, mApiKey);
}