The following code works as expected on Grails 2.0.4 and Eclipse STS 3.2 using Eclipse's embedded tcServer 2.7 as the web container...
class TestController {
def service() {
println request.request.getRequestURL()
//render response here...
}
For a client request of http://svr1:8080/testapp/test/node1, the above code prints the full request URL, http://svr1:8080/testapp/test/node1.
We created a WAR and deployed it to Jetty 8.1.10, but found that request.request returns null, so the above code fails with a null pointer. We tried using request.getRequestURL() but it returns a URL containing grails dispatch syntax, so it does not match the original client request url which is what we need.
As a workaround, we manually constructed most of the URL using request.getServerName(), request.getServerPort(), and request.getContextPath(), giving http://svr1:8080/testapp, but that still leaves out the uri portion, /test/node1. We assume this problem may be attributed to Jetty's Servlet API implementation, but if that were the case surely someone else would have picked up on this before us.
Found a workaround that appears to work on tcServer and Jetty posted here. We construct the base URL manually, then use this utility to get the remaining portion.
Related
We are running a service behind an nginx proxy so that:
http://service-post:8080/swagger-ui.html is routed to public address https://host.com/services/post/swagger-ui.html
Or to define from the other way:
When nginx receives request on https://host.com/services/post/swagger-ui.html, it strips the /services/post/ prefix and passes the request to the post service on /swagger-ui.html path.
Before setting up anything (with default SpringDoc configuration) I can correctly see the swagger docs on http://service-post:8080/swagger-ui.html.
To set the paths for the public address on host.com, I am using:
springdoc.api-docs.path: /services/post/api-docs
springdoc.swagger-ui.path: /services/post/swagger-ui.html
springdoc.swagger-ui.configUrl: /services/post/v3/api-docs/swagger-config
However it seems that this brakes it completely:
/swagger-ui.html, /api-docs and /v3/api-docs/swagger-config return 404 both for service-post:8080/* and https://host.com/services/post/*
Only thing that seems to work is https://host.com/services/post/swagger-ui/index.html which shows the petstore documentation.
We are not using Spring Boot, just Spring MVC of version 5.3.1.
So how do I set up to keep the handling of the original paths (eg. /api-docs), but performing the lookup on the prefixed path (/services/post/api-docs)?
In the end I completely ignore the default redirect:
swagger-ui.html -> `swagger-ui/index.html?url=/v3/api-docs
And implemented my own one:
docs -> swagger-ui/index.html?url=MY_PREFIX/v3/api-docs
This way I don't need to change anything and everything works with default settings.
It's all documented here:
https://springdoc.org/index.html#how-can-i-deploy-springdoc-openapi-ui-behind-a-reverse-proxy
If you are not using spring-boot, you can add the ForwardedHeaderFilter bean:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/ForwardedHeaderFilter.html
I've been working with the grails plugin: 'grails-rest-client-builder:2.0.1'
https://github.com/grails-plugins/grails-rest-client-builder/
I'm experiencing an odd issue when I POST some data to a web service, a 500 Exception, even though the POST indeed is working successfully.
Class
java.lang.NoClassDefFoundError
Message
org/springframework/util/StreamUtils
Around line 195 of PageFragmentCachingFilter.java
if (CollectionUtils.isEmpty(cacheOperations)) {
log.debug("No cacheable annotation found for {}:{} {}"
new Object[] { request.getMethod(), request.getRequestURI(), getContext() });
chain.doFilter(request, response);
return;
}
The response that is coming back from the web service should look like this:
{"id":"9999","key":"IX-2247","self":"https://jira.xxxx.com/rest/api/latest/issue/9999"}
Again, the web service is correctly getting the values that I pass into it, and I verified this by checking the application that I'm posting to and I do see what I expect. Not only that, but I also receive an email from the system that I am POSTing to, and the email contains the correct values from the Grails application.
Here's the POST that I'm using:
def rest = new grails.plugins.rest.client.RestBuilder()
def resp = rest.post("https://jira.xxxx.com/rest/api/latest/issue/"){
auth "Basic xxxx"
contentType "application/json"
json builder.toPrettyString()
}
My hypothesis is that perhaps the issue is that the rest-client-builder is having some kind of issue with the response that is being returned from the web service.
Has anyone encountered anything like this before, where the service is working, but Grails throws a 500 error, even on a successful POST?
Please let me know if I need to provide additional information.
Thanks in advance!
Thank you all for the replies. I ended up upgrading my Grails application to 2.3.5, from 2.2.3 and now the code (above) works perfectly. The 500 error disappeared completely.
I have never used JUnit or other testing frameworks. All i know is how to develop rest service. I recently saw REST assured framework to test REST api. But all the articles that i found looks like below. But i don't know how to pass request xml and how will i get response and when should i call this method.?
Do i need to use some other tool before this REST assured.? I am completely beginner in this kind of testing frameworks. Please show me some light in this world. All i know is how to send request and check values in the response in SOAPUI. I have never tried this.
expect().
statusCode(200).
body(
"user.email", equalTo("test#hascode.com"),
"user.firstName", equalTo("Tim"),
"user.lastName", equalTo("Testerman"),
"user.id", equalTo("1")).
when().
get("/service/single-user/xml");
expect() /* what u expect after sending a request to REST Service */
statusCode(200) /*you are expecting 200 as statuscode which tells request handled successfully at server */
body()
/* the conditions given in body are compare the value with expected values. "equalTo" hamcrest matcher condition (you need to have hamcrest jar in java classpath).*/
when(). /* as is name says above all will be done after sending get/post/put/delete request right so before you put these get,post,put,delete you will have this method as prefix */
get("/service/single-user/xml")
/* the actual REST API request url goes here. can be GET/POST/PUT/DELETE. the confusion for you is its only showing half part which is base path.you can give entire request url in get() method.*/
more on:
http://rest-assured.googlecode.com/svn/tags/1.8.1/apidocs/com/jayway/restassured/RestAssured.html
I hope this helps.
I've got a simple Grails app (1.3.7) in which I'm testing exceptions and returning specific HTTP status codes to the client.
I've disabled the default "500" (view: '/error') in URLMappings to prevent Grails from rendering the response using the standard error view.
I've got a simple closure in my controller to which I redirect, after catching an exception, and render the response...
def remoteError = {
response.status = 500
render ([__error: "A remote error occurred"] as JSON)
}
On one instance of WebLogic 10.3, when the test exception is thrown, the response is as follows...
{
__error: "A remote error occurred"
}
..exactly what I expected.
But the same exact WAR file deployed to another WebLogic 10.3 instance produces the standard Grails error page, seen below. Since the WAR file did not change, I'm trying to figure out what setting in WebLogic is causing this to behave differently compared to the other instance.
Turns out this problem was related to a missing plugin in our deployment WAR. On one instance of WebLogic, the plugin was in the maven/ivy cache, but on the other it was not, and this is why the WAR appeared to behave differently.
I want to create a proxy controller in grails, something that just takes whatever is passed in based on a url mapping, records what was asked for, sends the request to another server, records the response, and send the response back to the browser.
I'm having trouble with when the request has an odd file extension (.gif) or no file extension (/xxx?sdcscd)
My url mapping is:
"/proxy/$target**"
and I've attempted (per an answer to another question):
def targetURL = params.target
if (!FilenameUtils.getExtension(targetURL) && request.format) {
targetURL += ".${response.format}"
}
but this usually appends .html and never the .gif or ?csdcsd
Not sure what to do as I might just write the thing in straight Java
Actually, the real answer was sitting in the post you linked to previously all along, by Peter Ledbrook:
Disable file extension truncation by adding this line to grails-app/conf/Config.groovy:
grails.mime.file.extensions = false
This will disable the usage of file extensions for format, but will leave the file extension on params.target. You can completely ignore response.format!