I want to expose my existing controller as a Restful service - rest

I have an application where I'm registering a user so user will enter his data on JSP page and the data will be save into DB, the flow will be JSP->dispatcher->controller->Service->Dao.
Now in MemberController which is delegating the request to the Service, has a method register() which will take the MemberDto as a parameter now and return the Successfull msg to the success.jsp page. Sometihng like user registered successfully.
public String Register(MemberDto memberDto)
Now I want to expose this same method as RestFul service using Jersey for partners and also use this same method within my application as a normal MVC flow. How can I acheive this

So u want to use Jersey so import the jersey library to support JAX-RS.
#Path("/classlevelpath")
public class MyController {
#POST
#Produces(MediaType.APPLICATION-XML)
#Path("/register")
public String Register(MemberDto memberDto) {
}
}
Be careful JAX-RS (Jersey is an implementaion) and Spring REST annotations are different.

Annotate your rest class with #RestController. The best practice is to create another controller. By you can see this answer if you want to transform your existing controller: https://stackoverflow.com/questions/33062509/returning-view-from-spring-mvc-restcontroller

Related

Autofac OWIN web api - load dependency based on request

How I can load a service dependency based on the route parameter?
My requirement is different, but I'll try to use a simple example.
A user can select the shipping provider (UPS, Fedex...) and the information is as part of the request model or route. Based on the route, I need to load the service class.
How it can be done in Autofac OWIN? Help on this will be appreciated
When you use the Autofac's OWIN integration, each request creates a new lifetime scope in which the current IOwinContext is registered, as you can see here.
You could then delegate the creation of your service to a factory that would take a dependency on IOwinContext.
public class MyServiceFactory
{
private readonly IOwinContext _context;
public MyServiceFactory(IOwinContext context)
{
_context = context;
}
public IService Create()
{
// inspect the context and determine which service you need
// you could return, dependending on, let's say, the URL
// - UpsService()
// - FedexService()
}
}
One thing you'll need to make sure is that you register your factory as InstancePerLifetimeScope since the IOwinContext will be different for each request.
Do you need to work at the OWIN layer, though? It will make things harder, and possibly a bit hacky, since OWIN is really just the HTTP layer, so there's no such thing as route data.
If you use ASP.NET Web API, you could base the factory on the current HttpRequestMessage if you use the RegisterHttpRequestMessage extension method.
You can then access route data through request.GetRequestContext().RouteData. Note that GetRequestContext is an extension method in the System.Net.Http namespace.
If you use ASP.NET MVC, you can register the AutofacWebTypesModule in the container, itself registering quite a few types in the container.
One of those is HttpRequestContext which has a RouteData property, so you can inject this one in the factory and apply your logic.

how to get HTTP request object in class implementing jackrabbit ExternalIdentityProvider

I am implementing custom external identity provider and to do this I need to implement ExternalIdentityProvider class from jackrabbit.
http://jackrabbit.apache.org/oak/docs/security/authentication/externalloginmodule.html
In normal case you would need to pass j_username and j_password and you can get these from values SimpleCredentials object
My question is that since I need to pass additional form parameter say for instance linkedin ID in my case, how do I achieve that?
#Component(
policy = ConfigurationPolicy.REQUIRE
)
#Service
public class RDBMSIdentityProvider implements ExternalIdentityProvider {
#Override
public ExternalUser authenticate(Credentials credentials)
throws ExternalIdentityException, LoginException {
//i can get username / password from credentials object
//how to get additional parameters from http request object?
}
Any input is highly appreciated.
Thanks!
The correct way to handle this is to have a custom AuthenticationHandler which creates an instance of a specific Credentials object with whatever parameters you need in it.
That said, if you are integrating with LinkedIn (and this is in AEM), you would be better served by integrating with the existing OAuth AuthenticationHandler. There is OOTB support for Facebook and Twitter, but the OAuth provider is designed to be pluggable for different OAuth Service Providers.

Set up default page and Dynamic Web Project, JAX-RS

I am trying to do a simple rest service sample with eclipse, galssfiash server, using jersey. I started project like webDynamic.I did servlet mapping with Application class.Without web.xml file:
#ApplicationPath("/rest/*")
public class ApplicationConfig extends Application{
public Set<Class<?>> getClasses(){
return new HashSet<Class<?>>(Arrays.asList(MyClass.class));
}
And for now everything work fine. Bath how do I set default page?
On sample, when someone or I putt in address bar of web explorer only project name like:
localhost:8080/name.of.the.project/. I wish to be presented first page like readme.xhtml where is explained rest service on sample. And if in url I add .../rest/ it will be returned by web service. How do I accomplish this. Or I can use web.xml for first page and can register sevlet with Application class?
Yes, if you are using the Applicationpath annotation, you don't need to specify servlet class in the web.xml again. You can use the web.xml to specify welcome page and still use your application class as is

Creating a Client using Spring MVC for a RESTful API

I'm new to Spring framework and REST concepts. I've been working on a project to grasp these concepts efficiently.
I'm building a quiz tool where a user can login using his credentials and take a quiz.
I've created a RESTful API for same using JAX-RS. And now I want to create a Client which will work over this API, using Spring MVC.
Is that possible and how to start with that ??
I mean, How do I use Spring MVC to create a Client for my RESTful API ??
some of my resources are -
GET /scorecard
GET /scorecard/{quizId}
GET /scorecard/{userId}
GET /quiz/{questionId}
POST /quiz/{questionId}
and so on..
I'm really confused about the design aspects about a client using Spring MVC. Do I include the logic of evaluating quiz,calculating & storing scores in the API or in the spring MVC client ??
Thanx in advance.
Here is an example of the first two endpoints implemented with Spring MVC:
#Controller
#RequestMapping(value = "/scorecard")
public class ScorecardController {
#Autowired
private ScorecardService scorecardService;
// GET /scorecard
#RequestMapping(method = RequestMethod.GET)
public List<Scorecard> getScorecards()
{
List<Scorecard> scorecards = scorecardService.getScorecards();
return scorecards;
}
// GET /scorecard/{quizId}
#RequestMapping(value = "/{quizId}", method = RequestMethod.GET)
public List<Scorecard> getScorecardsByQuizId(#PathVariable long quizId)
{
List<Scorecard> scorecards = scorecardService.getScorecardsByQuizId(quizId);
return scorecards;
}
}
I would suggest checkout spring mvc showcase project from Github and experimenting with source code.
spring-mvc-showcase
You can easily use your browser as client for quite a few REST calls.
Design for application depends on requirements. e.g.
Keeping the score at client will keep you free from session management otherwise you will need to handle at server.

Spring MVC authorization in REST resources

I have REST api for accessing "parties" and the URL's look like this:
/parties
/parties/{partyId}
Using Spring controllers and #PathVariable I'm able to implement this interface. But to prevent users from accessing parties they don't have access to, I have to add checks to every method call which is kind of repeating myself and I might forget to add it everywhere:
#RequestMapping(value="/parties/{partyId}", method=RequestMethod.GET)
public #ResponseBody Party getParty(#PathVariable Integer partyId){
authorizeForParty(partyId);
...
Now what I would like to do is create a check that would be called every time that user enters url like this:
/parties/{partyId}/**
How would I do something like this? Do I have to create some servlet filter and parse the url myself? If I have to parse the url then is there atleast tools that would make it easy? I wish there was a way to add a method to controller that would be called before methods but could still use #PathVariables and such...
What I ended up with is using the Spring MVC interceptors and parsing the path variables in the same way that Spring does. So I define an interceptor for the REST url:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/parties/*/**" />
<bean class="PartyAuthorizationInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
The PartyAuthorizationInterceptor has to implement HandlerInterceptor in which we have to implement preHandle. It has HttpServletRequest as a parameter so we can get the request URL but we still have to parse the partyId from the url. After reading how Spring MVC does it, I found out they have a class named org.springframework.util.AntPathMatcher. It can read the path variables from the URL and place the values in a map. The method is called extractUriTemplateVariables.
So the result looks like this:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String partyIdStr = new AntPathMatcher().extractUriTemplateVariables("/parties/{partyId}/**", request.getPathInfo()).get("partyId");
...
That makes the parsing almost as easy as using #PathVariable in MVC Controller methods. You still have to do conversions yourself(e.g. String -> Integer).
Now I can implement authorization logic on all urls that access a party in this interceptor and keep that logic out of the individual controller methods. Not as easy as I would have hoped but it gets the job done.
Are you already using some kind of security library in your application, e. g. Spring Security?
Because the kind of logic you want to implement is a classic case for an AccessDecisionVoter in an authentication chain. You would just put your API behind Spring Security's protection and implement the custom check as part of the security chain.
If you are not using a security framework at all, your idea of implementing a HandlerInterceptor may be the best alternative, though. But it would require you (as you mentioned) to take into account all kinds of obfuscation the user may use in order to gain access to other URLs (e. g. %-encoding of letters, ../../ patterns etc.).