I am trying to incorporate Spring HATEOAS into an existing service tool and REST API. However, one of the issues I"m encountering is that the ControllerLinkBuilder seems to remove trailing slashes (which is a requirement due to existing constraints). Is there some workaround or method to get that trailing slash added to the link?
user.add(linkTo(UserController.class).slash("user").slash(user.getUsername() + "/").withRel("Get User Details"));
(User extends ResourceSupport)
I have also tried .slash("") to no avail.
The output:
"http://localhost:8080/REST/user/<username>"
Not just using link builder as far as i can see. LinkBuilders use UriComponents to parse it out. Then it goes through each segment and adds them back into the a UriComponents builder. stuff/ goes in the UriComponents but stuff is all that comes out.
What you can do is make that a Link in a round about way, eg:
user.add(
new Link(
linkTo(UserController.class).slash("user").slash(user.getUsername())
.toUriComponentsBuilder().build().toUriString() + "/",
"Get User Details"
)
);
there's probably an easier way...but you get the idea. Link doesn't seem to shove you through the UriComponents stuff
Related
I'm using Spring Boot 2.4.6. For delete APIs getting 405 method not found. My endpoint is like: beauty/v1/sites/addressTemplates/:templateId
Path variable: ##$%#
Can someone please suggest what can be done to make this behavior as not complaining for 405? Please direct me to other questions in case I'm missing something.
I guess that your issue has nothing to do with Spring. Maybe you are trying to compose the whole URL by using reserved characters.
In a URL, a hash mark, number sign, or pound sign ( # ) points a browser to a specific spot in a page or website. It is used to separate the URI of an object from a fragment identifier. Source.
Which means that an URL which looks like:
beauty/v1/sites/addressTemplates/##$%#
is not exactly what you imagine it to be because # is interpreted in a special way. What you have to do is to percent encode the "special" path variable so it will look like this at the end:
beauty/v1/sites/addressTemplates/%23%40%24%25%23
Then Spring will not complain anymore and will resolve properly the endpoint.
I'm following the examples here -> https://github.com/apache/camel-k-examples. Working on 05-knative-source-jira
When running this integration, I'm able to read and log new jira issues just fine, I fall down when I try to use info from the ticket, or respond to the ticket with the jira addComment producer.
I've tried just putting a static ticket number in for the IssueKey option, but I get build errors and can't even get the producer to run.
I've tried tinkering with the URI...
Ex: Changing URI to -> .to("jira://addComment?IssueKey=EQ-7") returns below on build
No signature of method: org.apache.camel.builder.ValueBuilder.to() is applicable for argument types: (String) values: [jira://addComment&IssueKey=EQ-7]
I've tried this with both ? and &, as well as adding properties to the URI with similar results.
I feel like I'm missing something pretty fundamental, so any docs pointers would be well appreciated.
Full integration here
// camel-k: language=groovy
from('knative:channel/jira')
.unmarshal()
.json()
.log('Recieved: ${body}')
.to('direct:ticket')
from("direct:ticket")
.setBody().simple("testing")
.to("jira://addComment?IssueKey=EQ-7")
I ended up sorting through enough docs to find the answer. I'll share details just for others who might find this (or if I google it again).
The key was to
a) Set the required headers for the issue key. Seting headers examples
b) Ensure that my properties are set correctly. I used a configmap to set my properties, and then referenced them as shown below in the URI. I believe this should also be possible through DSL but URI was easiest for me to just get working.
Functional Integration below.
from("direct:ticket")
.setHeader("IssueKey").simple('${body["key"]}')
.setBody().simple("We've recieved the ticket -- we'll update you soon!")
.to("jira://addComment?jiraUrl={{url}}&consumerKey={{consumer_key}}&accessToken={{access_token}}&privateKey={{private_key}}&verificationCode={{verification_code}}")
I am working to modernize old legacy code, and while doing that ran into some deprecated constructs that I can't figure out how to handle. They all look somewhat like this:
HttpPost oauthVerificationRequest = new HttpPost(authURL);
oauthVerificationRequest.getParams().setParameter(OAUTH_TOKEN_KEY, oauthToken);
HttpResponse oauthVerificationRequestResponse = client.getHttpClient().execute(oauthVerificationRequest);
There, my IDE complains that both getParams() as well as setParameter is deprecated.
The thing is, written as it is like this, I understand exactly what is happening. The deprecated line sets the value of the parameter with the key OAUTH_TOKEN_KEY of the request to the value of oauthToken, and probably creates it if it doesn't exist.
However, even knowing that this is what is supposed to happen in this line, I have been unable to find a way to write this line in a modern way. I've tried to figure it out, but the new way of constructing a AbstractHttpMessage simply confuses me.
Since I learn best by examples, could someone please provide me with a "translation" of the above code to the new logic?
Okay, once again it seems that writing down my thoughts as a question helped get my mind down on the right track to find the solution. So to answer my own question, the correct way to write above statement in the new logic would be:
URIBuilder oauthVerificationRequestBuilder = new URIBuilder(authUrl);
oauthVerificationRequestBuilder.setParameter(OAUTH_TOKEN_KEY, oauthToken);
HttpPost oauthVerificationRequest = new HttpPost(oauthVerificationRequestBuilder.build());
HttpResponse oauthVerificationRequestResponse = client.getHttpClient().execute(oauthVerificationRequest);
So basically, you first create a builder, then set the parameters inside the builder, and then create the request using builder.build() as its parameter.
Bonus Question:
Is there also a way to get the addHeader() modification into the builder? Because right now, the entire construct looks like this for me, and it feels kinda inconsistent to use the builder for the parameters, and then slapping the header on top of the request the "old fashioned" way:
URIBuilder oauthVerificationRequestBuilder = new URIBuilder(authUrl);
oauthVerificationRequestBuilder.setParameter(OAUTH_TOKEN_KEY, oauthToken);
oauthVerificationRequestBuilder.setParameter(OAUTH_VERIFIER_KEY, oauthVerifier);
oauthVerificationRequestBuilder.setParameter(AUTHORIZE_KEY, VALUE_STRING_TRUE);
HttpPost oauthVerificationRequest = new HttpPost(oauthVerificationRequestBuilder.build());
oauthVerificationRequest.addHeader(CONTENT_TYPE_KEY, CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED_UTF_8);
Googling "java httppost" gives a link to the documentation. Looking for getParams() in the docs, shows that it is inherited from AbstractHttpMessage and another google search found the docs for that class. That docs explains what to do instead of using the deprecated method:
Deprecated. (4.3) use constructor parameters of configuration API provided by HttpClient
I hope this helps some future reader. Good libraries will document what the suggested replacement is for deprecated methods. It's always a good idea to consult the documentation for these suggestions.
It's very simple by http-request built on apache http API.
HttpRequest httpRequest = HttpRequestBuilder.create(
ClientBuilder.create().build();
)
.build();
Response response = httpRequest.target(authURL)
.addParameter(OAUTH_TOKEN_KEY, oauthToken)
.addParameter(ANOTHER_PARAM, "VALUE")
.addHeader(ANY_HEADER, "VALUE")
.post();
Dependency
<dependency>
<groupId>com.jsunsoft.http</groupId>
<artifactId>http-request</artifactId>
<version>2.2.2</version>
</dependency>
I'm trying to get my Spring 4 application to allow Path Parameters that end with an escaped slash.
The #RequestMapping I've got is:
#RequestMapping("/{externalSystemId}/{externalRequestId}/events")
And the URL that I'm calling with is /dummy/ab%2F/events. So "externalRequestId" is the one that has the trailing encoded slash.
I've gotten to the point where the handler is called correctly, and where escaped slashes in the middle of the path segment work - e.g. /dummy/ab%2Fcd/events, but not at the end.
What I've done so far:
Added system properties to Tomcat:
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true
-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
Custom extension of UrlPathHelper that replaces getServletPath with one that simply returns request.getRequestURI()
Configure the UrlPathHelper with:
urlDecode = false
removeSemicolonContent = false
Use this UrlPathHelper from mvc:path-matching, within mvc:annotation-driven
And I'm at a complete loss as to where to go next. I've even been debugging through both Spring and Tomcat to try and work it out, and I'm stumped. It looks like it's because UrlPathHelper.getPathWithinServletMapping() is calling request.getPathInfo(), and that is returning the path with the %2F stripped out. And that in turn is because somewhere else in Tomcat - I've lost the window now - it has decoded the %2F into a /, then replaced the "//" that is now present with a "/" instead.
This feels like it should be relatively straightforward, so what am I missing?
I've tried it on both Tomcat 7 and Tomcat 8, and with various versions of Spring 4 - currently on 4.3.14.
Problem solved.
The SlashFriendlyUrlPathHelper that I had that was the extension of UrlPathHelper was causing problems, because my webapp is not the Root webapp. Remove that, but keep every other change in place, and it starts to work properly.
Original Question: https://github.com/howtographql/graphql-java/issues/4
AuthContext context = env.getContext();
Link newLink = new Link(url, description, context.getUser().getId());
I do not get null on context variable, but I get a null on context.getUser()
code:https://github.com/howtographql/graphql-java/blob/master/src/main/java/com/howtographql/hackernews/Mutation.java
or my code:
https://github.com/JonathanSum/myOwnJavaGraphqlStarterKit/blob/master/src/main/java/com/howtographql/hackernews/Mutation.java
I'm the author of that tutorial, which is now unfortunately very outdated... I'm working on rewriting it in pure graphql-java (without graphql-java-tools), and this is what I'd recommend you try as well.
For the time being, your issue is very likely either because the browser doesn't send the user ID (in the Authorization header) at all or, if it does, it doesn't match the ID in Mongo.
Put a break point in createContext method in GraphQLEndpoint and inspect what happens.
The tutorial explains the code you need to add to the client to start sending the Authorization header, so make sure you followed that. otherwise, just make sure the ID it sends matches what you have in Mongo.