Dropwizard UriInfo contain invalid baseUri - dropwizard

I've faced a problem when I get base URI form uriInfo. Here's a part of code:
#Path("/users")
#POST
public Response createUser(#RequestBody User user, #Context UriInfo uriInfo) {
...
String confirmEmailUrl = uriInfo.getBaseUri().resolve("/users/confirm/" + getConfirmEmailLink(user));
...
}
confirmEmailUrl must be like http://XXX.XXX.XXX.XXX:8080/users/confirm/aergserthserg but I get the following result http://XXX.XXX.XXX.XXX/users/confirm/aergserthserg. The problem within the port. I used in some other methods uriInfo to build the URL and it works correctly. What is wrong here?

Related

Hybris + swagger integration swagger-ui.html UnknownResourceError

I'm trying to integrate swagger in MYcommercewebservices.
I read post and done all steps listed on it, but still having this error.
https://localhost:9002/mycommercewebservices/v2/v2/api-docs working fine. https://localhost:9002/mycommercewebservices/v2/swagger-ui.html - return UnknownResourceError.
Furthermore - if I navigate to https://localhost:9002/mycommercewebservices/swagger-ui.html (without 'v2') it'll show me this message (javascript alert):
Unable to infer base URL. This is common when using dynamic servlet
registration or when the API is behind an API Gateway. The base URL is
the root of where all the swagger resources are served. For e.g. if
the API is available at http://example.org/api/v2/api-docs then the
base URL is http://example.org/api/. Please enter the location
manually:
I found this controller, and probably part of the problem was in it because it was throwing an exception when I navigated to https://localhost:9002/mycommercewebservices/v2/swagger-ui.html
#Controller
public class DefaultController
{
#RequestMapping
public void defaultRequest(final HttpServletRequest request)
{
throw new UnknownResourceException("There is no resource for path " + YSanitizer.sanitize(request.getRequestURI()));
}
}
Now I disabled controller, but still having the same exception, but now it's in json format instead of .xml.
Thank you!
The main problem was in DefaultController (in MYcommercewebservices)
#Controller
public class DefaultController
{
#RequestMapping
public void defaultRequest(final HttpServletRequest request)
{
throw new UnknownResourceException("There is no resource for path " + YSanitizer.sanitize(request.getRequestURI()));
}
}
It was catching my request and throwing the exception.
When I disabled this controller, I continued to receive an exception, but now it was in json format(before it was in xml).
Than I added this to springmvc-v2-servlet.xml
<mvc:default-servlet-handler/>
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/"/>
<mvc:resources mapping="/webjars/**" location="classpath:/META-INF/resources/webjars/"/>
Now UI works fine!
Also there were another manipulation before all this, but you can find them in hybris experts(quite big post).

Dropwizard sends back 404 Not Found for part of registered endpoints

I have a simple resource which exposes CRUD endpoints.
#Path("/stores/{store-id}/register")
#Produces(MediaType.APPLICATION_JSON)
public class RegisterResource {
#GET
#Path("/{register-id}")
public Response getRegisterById(#PathParam("store-id") Long storeId, #PathParam("register-id") Long registerId) { impl }
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response save(RegisterDTO registerDto, #PathParam("store-id") Long storeId, #Context UriInfo uriInfo) { impl }
#PUT
#Path("/{register-id}")
#Consumes(MediaType.APPLICATION_JSON)
public Response update(RegisterDTO registerDto, #PathParam("store-id") Long storeId, #PathParam("register-id") Long registerId) { impl }
#DELETE
#Path("/{register-id}")
public Response delete(#PathParam("store-id") Long storeId, #PathParam("register-id") Long registerId) { impl }
}
Dropwizard successfully register my resource:
INFO [2017-03-07 07:03:49,765] io.dropwizard.jersey.DropwizardResourceConfig: The following paths were found for the configured resources:
POST /stores/{store-id}/register (api.resources.RegisterResource)
DELETE /stores/{store-id}/register/{register-id} (api.resources.RegisterResource)
GET /stores/{store-id}/register/{register-id} (api.resources.RegisterResource)
PUT /stores/{store-id}/register/{register-id} (api.resources.RegisterResource)
Only POST requests are processed. When I send GET/PUT/DELETE request - I receive back 404 Not Found. No exceptions are thrown/logged.
There are also two interesting facts:
1) I have a filter which checks Authorization header. It does not log any requests except POST.
2) I log incoming request int the first statement of every method of my resource. But only requests for POST are logged.
The most interesting fact is that I a day ago and everything was OK. Can't figure out where the problem is... I will appreciate any suggestions what went wrong.

Attribute routing is failing for MVC/WebApi combo project

I am trying to create an ASP.NET app that is both MVC and Web Api. The default controller (HomeController) returns a view that is composed of some HTML and jQuery. I would like to use the jQuery to call the API that is part of the same project.
I have the API setup and have been testing it with Postman but I get the following error when trying to reach the endpoints in the API.
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:19925/api/encryption/encrypt'.",
"MessageDetail": "No action was found on the controller 'Values' that matches the request."
}
I am attempting to use attribute routing so I am pretty sure that is where I am going wrong.
[RoutePrefix("api/encryption")]
public class ValuesController : ApiController
{
[HttpPost]
[Route("encrypt")]
public IHttpActionResult EncryptText(string plainText, string keyPassPhrase)
{
// Method details here
return Ok(cipherText);
}
}
I have the route prefix set to api/encryption. I also have the method using the route encrypt and marked as a HttpPost. Below is my WebApiConfig which I think is configured properly for attribute routing.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
// Default MVC routing
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
By my understanding a POST to the following URL should reach the method ..
http://localhost:19925/api/encryption/encrypt
yet it isn't. I am posting the two string values to the method via Postman. I have attached a screen capture (and yes the keyPassPhrase is fake).
Here is the global.asax as requested ...
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
One other thing to note ... that when I change from GET to POST in Postman it works .. as long as I am sending the parameters along in the query string. If I send the parameters in the body I get the original error.
The problem was that I was trying to POST two values to an API method that accepted two parameters. This is not possible with the API (well not without some work arounds) as the API method is expecting an object rather than two different primitive types (i.e. String).
This means on the server side I needed to create a simple class that held the values I wanted to pass. For example ...
public class EncryptionPayload
{
public string PlainText { get; set; }
public string PassPhrase { get; set; }
}
I then modified my API method to accept a type of this class
[Route("encrypt")]
[HttpPost]
public IHttpActionResult EncryptText(EncryptionPayload payload)
{
string plainText = payload.PlainText;
string passPhrase = payload.PassPhrase
// Do encryption stuff here
return Ok(cipherText);
}
Then inside that controller I pulled the Strings I needed from the EncryptionPayload class instance. On the client side I needed to send my data as a JSON string like this ..
{"plainText":"this is some plain text","passPhrase":"abcdefghijklmnopqrstuvwxyz"}
After changing these things everything worked in Postman. In the end I wasn't taking into account Model Binding, thinking instead that an API endpoint that accepted POST could accept multiple primitive values.
This post from Rick Strahl helped me figure it out. This page from Microsoft on Parameter Binding also explains it by saying At most one parameter is allowed to read from the message body.
Try the following code. It will work :
[RoutePrefix("api/encryption")]
public class ValuesController : ApiController
{
[Route("encrypt"),HttpPost]
public IHttpActionResult EncryptText(string plainText, string keyPassPhrase)
{
// Method details here
return Ok(cipherText);
}
}
Sorry dear it was really compile time error. I edit my code. Please copy it and paste it in yourcode. Mark as answer If i Helped.

Grails, how to get the request object

Grails has a request object which is defined here.
The problem is when I try to use it, I get:
No such property: request for class:xxx
Reading the first 100 hits googling this error only produced one suggestion:
import javax.servlet.http.HttpServletRequest
import org.springframework.web.context.request.ServletRequestAttributes
:
def my() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
}
However, this gives:
groovy.lang.MissingPropertyException: No such property: RequestContextHolder for class: net.ohds.ReportService
How does one get a handle on the request object in Grails?
How do you find out about this? So few people have asked this question, it must be documented somewhere, or in some example, but I can't find either.
In Grails 3.0, from a service get the request object using:
grails-app/services/com/example/MyService.groovy
import org.grails.web.util.WebUtils
...
def request = WebUtils.retrieveGrailsWebRequest().getCurrentRequest()
def ip = request.getRemoteAddr()
Documentation:
https://docs.grails.org/latest/api/org/grails/web/util/WebUtils.html#retrieveGrailsWebRequest()
Note:
The old codehaus package has been deprecated.
Try following code:
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
import org.codehaus.groovy.grails.web.util.WebUtils
...
GrailsWebRequest webUtils = WebUtils.retrieveGrailsWebRequest()
def request = webUtils.getCurrentRequest()
I expect that you probably got "groovy.lang.MissingPropertyException: No such property: RequestContextHolder for class: net.ohds.ReportService" because you didn't import the "org.springframework.web.context.request.RequestContextHolder" class in your ReportService.
The most common place to want access to the request object is in a controller. From a controller you simply refer to the request property and it will be there. See http://grails.org/doc/latest/ref/Controllers/request.html.
The answer to how to access the request object from somewhere else may depend on what the somewhere else is.
UPDATE
I don't know why you are having trouble passing the request from a controller to a service, but you can. I suspect you are invoking the method incorrectly, but something like this will work...
// grails-app/services/com/demo/HelperService.groovy
package com.demo
class HelperService {
// you don't have to statically type the
// argument here... but you can
def doSomethingWithRequest(javax.servlet.http.HttpServletRequest req) {
// do whatever you want to do with req here...
}
}
A controller...
// grails-app/controllers/com/demo/DemoController.groovy
package com.demo
class DemoController {
def helperService
def index() {
helperService.doSomethingWithRequest request
render 'Success'
}
}

Getting the base url of my server with JAX-RS

How do I get the base url of my server with JAX-RS? Basically I want ""http://localhost:8080/.." when the program is on localhost and "http://www.theSite.com/..." when the program is on a live server. I am using Jersey Framework.
Yes, you may use myUri = uri.getBaseUri();
Here how you get the Uri object :
#Path("myresource")
public class MyResource{
#Context
UriInfo uri;
#GET
public String myresponse(){
URI myUri = uri.getBaseUri();
return ...
}
}
You will have plenty of informations with UriInfo. Check here the javadoc.
Use getBaseUri() of #Context UriInfo.

Resources