I'm developing an app with a Flex-based front end and a Spring/Hibernate back-end.
To get Facebook integration working in the way I've got it currently, I need to read the cookies set in javascript on the front end on the back-end and do some validation during login to see whether the user is attempting to spoof his Facebook login.
This would be pretty easy, but I can't figure out how to get the HttpServletRequest. I'm using a pretty basic Spring config (this is my first real Spring app, and I'm pretty familiar with it now, but there's lots to it I've never looked at.)
I'm not using Spring MVC or Spring WebFlow or anything like that. I can get the ServletContext, but I haven't yet figured out how to get the request.
Any help?
If FlexContext is not available:
Solution 1: inside method (>= Spring 2.0 required)
HttpServletRequest request =
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
.getRequest();
Solution 2: inside bean (supported by >= 2.5, Spring 3.0 for singelton beans required!)
#Autowired
private HttpServletRequest request;
This is kind of Flex/BlazeDS specific, but here's the solution I've come up with. Sorry if answering my own question is a faux pas.
HttpServletRequest request = flex.messaging.FlexContext.getHttpRequest();
Cookie[] cookies = request.getCookies();
for (Cookie c:cookies)
{
log.debug(String.format("Cookie: %s, %s, domain: %s",c.getName(), c.getValue(),c.getDomain()));
}
It works, I get the cookies. My problem was looking to Spring - BlazeDS had it. Spring probably does too, but I still don't know how to get to it.
#eeezyy's answer didn't work for me, although I'm using Spring Boot (2.0.4) and it may differ, but a variation here in 2018 works thus:
#Autowired
private HttpServletRequest request;
this should do it
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getRequestURI();
The #Context annotation (see answers in this question :What does context annotation do in Spring?) will cause it to be injected for you.
I had to use
#Context
private HttpServletRequest request;
Better way is to autowire with a constructor:
private final HttpServletRequest httpServletRequest;
public ClassConstructor(HttpServletRequest httpServletRequest){
this.httpServletRequest = httpServletRequest;
}
Related
We are trying to have a spring MVC Controller that works as a portlet and a servlet, in order to be deployed in a Liferay context or as a standalone version. But it seems that the we have a conflict if we decide to have multiple RequestMappings on the method level (as opposed to having just 1 mapping on the level of the controller). we get the error shown below.
Note that if we decide to just have a requestMapping on the level of the controller that hosts a servlet mapping and a portlet mapping, it works.
#RequestMapping({"view", "/"})
The controller that does not work:
#Controller("controller")
#RequestMapping("VIEW")
public class MyController {
#RenderMapping
public ModelAndView doView(RenderRequest request, RenderResponse response) throws Exception {
HttpServletRequest portletHttpReq = PortalUtil.getHttpServletRequest(request);
HttpServletResponse portletHttpResp = PortalUtil.getHttpServletResponse(response);
return doView(portletHttpReq, portletHttpResp);
}
#RequestMapping(value="/home")
protected ModelAndView doView(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
// do something
return new ModelAndView("view");
}
}
The resulting error:
[...]
Caused by: java.lang.IllegalStateException: Mode mappings conflict between method and type level: [/home] versus [view]
Do you have any suggestions on how we could implement such thing? What we would really like to avoid is having to maintain 2 controllers for every portlet/servlet.
Thank you.
I don't really think this is a good idea... the #RequestMapping annotation on the class level is going to cause problems for sure, simply because Spring portlet MVC expects the portlet mode, while Spring Web MVC expects a root URL.
Also, your code doesn't seem to be correct either, since ModelAndView exists in both the portlet MVC as the web MVC part of the Spring framework, and since you cannot import both, you'll have to specify the full package for one of them, and since you're not doing that either, your code is just wrong.
Except the technical issues, both portlets and servlet have different terminology and point of views. These are some key questions that pop up with me if I hear this:
What are you going to do about the different phases (ACTION and RENDER)
What about the the different portlet modes (VIEW, EDIT, HELP, ...)
What are you going to do about the specific portlet features (PortletSession, PortletPreferences, ...)
How are you going to handle the different kind of requests (ResourceRequest, ActionRequest, RenderRequest, PortletRequst, EventRequest vs HttpServletRequest)
How are you going to handle security? The portal container provides authentication for you, a standalone web application does not.
And these are just questions from a portlet mindset, I'm pretty sure there are also technical issues if you look at it from the web application point of view.
It makes much more sense to divide your code into a view layer and business logic. Put the business logic in a separate package or separate services, and build a separate portlet- and standalone application, using the same/shared business logic.
I came across authentication code in my company's java code. The application is a set of several REST services built on Spring MVC. There is a method that gets called in one of the authentication services on the HttpServletRequest object called getHeader(). And the method retrieves an AuthId. Why would they use HttpServletRequest in a spring MVC application? What are the benefits of using this servlet type code in the spring app? What would this method do? Any alternatives?
Spring MVC provides a lot of fabulous abstractions on top of HttpServletRequest, so you can avoid its low-level implementation details. You rarely need to access it directly.
For example, you could get a header value like Content-Type like this:
#GET
#Path("/myService")
public Response doSomething(#HeaderParam("Content-Type") String contentType) {
...
}
But there are times when you do need to access the HttpServletRequest directly--usually when you are using another API that demands it. If you are using some other library with a method you need that takes HttpServletRequest, then you got to grab it from Spring MVC directly.
For example, check out this method in this random UrlUtil class:
public static String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
//Get a path segment
}
You have no choice but to grab HttpServletRequest from Spring MVC.
Spring MVC is built on the Servlet API. Anything you could do with a Servlet, you can therefore do with Spring MVC. What the Spring MVC framework provides is a wrapper to code a web application in a specific architectural style. This wrapper adds behavior and some times simplifies tasks.
Why would they use HttpServletRequest in a spring MVC application?
In this case, because it is the most direct way to get the header.
What are the benefits of using this servlet type code in the spring
app?
Spring doesn't have to wrap anything. You get it directly from the source.
What would this method do?
Read the javadoc.
Any alternatives?
In a #Controller class' handler method, you can declare a parameter annotated with #RequestHeader and have Spring pass an argument that it retrieves from the HttpServletRequest headers.
This is, by default, restricted to #Controller methods annotated with #RequestMapping. If your service class is a HandlerInterceptor, Filter, or other type of class and simply has a reference to the HttpServletRequest object, there is nothing more you can do than retrieve it directly with getHeader(String).
Here is an alternative : Spring MVC define the parameter annotation #RequestHeader to read httpServletRequest headers :
#RequestMapping(...)
public #ResponseBody String myMethod(#RequestHeader String AuthId){
//the value of the parameter AuthId is the value of request header named AuthId
...
}
In PHP when a user logs into her account, I do the following in order to remember the user as she navigates through the site:
session_start();
...
$_SESSION['username'] = $username;
On any other page that may require sensitive data, I check that $_SESSION['username'] is valid.
When a use logs out, I do the following
unset($_SESSION['username']
session_destroy();
How do I do the same thing in Java? I have a REST API which uses Jersey and EJB. In case the following is important, I am persisting with JPA, Hibernate, Glassfish, and mysql.
UPDATED FOR VERIFICATON:
Is this correct?
#Path("login")
public class UserLoginResource {
#EJB
private LoginDao loginDao;
#Context
HttpServletRequest request;
#POST
public Response login(JAXBElement<Login> jaxbLogin){
Login login = jaxbLogin.getValue();
loginDao.authenticateUserLogin(login);
HttpSession session = request.getSession();
session.setAttribute("username", login.getUsername());
return Response.ok().build();
}
}
Java is very different from php, so in java You will get session from only HttpRequest 's getSession() method, In php it is all time assumed, your code is run by some server(ie apache), In java, you will obtain it from ServletContainer(ie Apache Tomcat).
You do not have to start session in java unlike php, As long as you are in servlet container and giving request, for this client servlet container is responsible to start if there is not session for it
So for above actions:
reqest.getSession().setAttribute("udername","Elbek");
//later
reqest.getSession().removeAttribute("udername");
//destroy it
reqest.getSession().invalidate();
Here request is object of HttpRequest class
You may have a look to this HttpSession
I strongly recommend you to have a look java scopes
There is not this kind of thing in php, I wish there is, BUT there is NO
Here is how you get request object into your jersey action(method), ie by injecting #Context HttpServletRequest httpRequest
EDIT:
You do not create HttpRequest object by yourself, Instead you will get it from servlet container, Your server creates it from clients request and gives for your.
+elbek describes plain servlet situation - however, nowadays almost nobody writes plain servlet. It sickes soo much back then, that a lot of web frameworks evolved. There is a sh*tload of them, but good ones will utilize dependency injection techniques like spring
( for example , struts 2 ) and there are distinct scopes - application / session / request - containing plain java beans, which can in turn have authentication data.
J2EE also provides own authentication semantics with servlet container and JAAS - it also uses session tracking and useful when you need to access some backend resources like datasources or queues or EJBs - but most web application do not bother wth it.
I have a REST- Server here using JERSEY. I must log the IP (better the DNS) of the calling client.
Can somebody point a direction which injection annotations to use ?
Searched "#Context", but could not find anything fitting.
Thanks
Gerd
you could add #Context HttpServletRequest request as a parameter to your request handler method. And then get a hold of the client IP with request.getRemoteAddr()
In case you use Grizzly-Jersey combo, thats the way to do it:
#Context
private java.lang.ThreadLocal<org.glassfish.grizzly.http.server.Request> grizzlyRequest;
Option 2 for Grizzly-Jersey combo.
Place in the declaration of the class (extender of ContainerRequestFilter in my case)
#Inject
private javax.inject.Provider<org.glassfish.grizzly.http.server.Request> request;
and later in the code use this.
request.get().getRemoteAddr()
I dug around and I've found the resolution in the jersey's jira.
Note that they recommend to be used #Inject instead of #Context
I've tried to use
#Context
private HttpServletRequest servletRequest;
which is recommended widely but servletRequest was always null.
*comment servletRequest was null because I was used GrizzlyHttpServerFactory for creating HttpServer. If you want to have servletRequest then you need to deploy it with WebappContext. Take a look here for details
I'm using Spring MVC and I want to store request specific values somewhere so that they can be fetched throughout my request context. Say I want to set a value into the context in my Controller (or some sort of handler) and then fetch that value from some other part of the Spring request/response cycle (could be a view, view resolver, interceptor, exception handler, etc)... how would I do that?
My question is:
Does Spring MVC already provide a method to do what I described above?
If Spring doesn't have this functionality, any ideas on the best way to do this (by extending something maybe)?
Thanks!
If you need to pass an object from your controller to view, you can use Spring's ModelMap.
#RequestMapping("/list")
public String list(ModelMap modelMap) {
// ... do foo
modelMap.addAttribute("greeting", "hello");
return viewName;
}
on your view:
<h1>${greeting}</h1>
You could use sessionAttributes.
Session Attributes
I took the latest version of the api (3.1) since you didn't mention your version of spring.