Tapestry internal redirection to static page - java

I just want a Tapestry page to redirect to a static page like this :
http://www.myWebSite.com/home/myPage.tml
-> http://www.myWebSite.com/static/myStaticPage.html
I try to do this by returning a new URL, but i need to know the web site address for that (http://www.myWebSite.com/). So, i would like to know how to do this without knowing the web site address ?
Thank you.

You can inject (using #Inject) the HttpServletRequest directly in your page directly, without using RequestGlobals, and use its getServerName() method to get the server name. Not tested:
#Inject
private HttpServletRequest request;
Object onActivate() {
return new java.net.URL("http://" + request.getServerName() " + "/myStaticPage.html");
}

Found : using the RequestGlobals service
String baseUrl = requestGlobals.getHTTPServletRequest().getRequestURL().toString().replaceFirst(requestGlobals.getHTTPServletRequest().getRequestURI(), "");
Just use it to build your URL string put it in a URL instance.

Related

Spring Cloud Zuul: RedirectView redirecting to service and not gateway

I'm a bit new to microservices and Spring. I have Spring Cloud microservices (ports: 8xxx-8xxx) with a Zuul gateway running on port 9000. There's a method inside a controller on a UI service which should do a login and then return to a index.html page:
#RequestMapping(value="/do-login", method = RequestMethod.POST)
public RedirectView doLogin (#ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
model.addAttribute(VERSION, applicationVersion);
model.addAttribute("authEntity", new AuthEntity());
authenticatedStatus = true;
model.addAttribute(AUTHENTICATED, authenticatedStatus);
return new RedirectView("index");
}
The problem is that when above method completes it returns an url of the microservice itself localhost:8888/index but not localhost:9000/services/ui/.
If I use a simpler method:
#RequestMapping(value="/do-login", method = RequestMethod.POST)
public String doLogin (#ModelAttribute("authEntity") final AuthEntity authEntity, final Model model) {
model.addAttribute(VERSION, applicationVersion);
model.addAttribute("authEntity", new AuthEntity());
authenticatedStatus = true;
model.addAttribute(AUTHENTICATED, authenticatedStatus);
return "index";
}
This returns correctly an url of gateway localhost:9000/services/ui/do-login but with a /do-login which I do not need.
Maybe I can get rid of /do-login/ part of url? Or maybe there is a solution for the incorrect redirect?
Thanks in advance!
If you use relative path like in return "index"; the result of the POST request sent to http://localhost:9000/services/ui/do-login will include URLs to http://localhost:9000/... unless coded otherwise in the jsp / freemarker / thymeleaf file.
If you want to get rid of the do-login, you would need to implement what's called a Redirect After Post (or redirect after form submit) approach so that a page refresh doesn't resubmit the form. If you take this approach, which seem what you were doing when using: return new RedirectView("index");, I can think of a couple ways of fixing the URL and set it to the proxy host.
1) http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/view/RedirectView.html, there are a couple of constructors that takes a host parameter, you would need to inject the proxy host in the controller class and most-likely in every controller class that implements Redirect After Post.
2) http://tuckey.org/urlrewrite/, include UrlRewriteFilter and configure rules to rewrite from webapp host to proxy host when webapp http status code response is 302. With this approach it would only be once rule and no need to inject proxy host to controller classes or change the return new RedirectView("index");`
3) Maybe this rewriting is implemented in Zuul and you don't need include and configure UrlRewriteFilter as suggested in 2).
As a side note, I have configured Nginx's proxy_pass to a Java webapps (where I implemented Redirect After Post) in the past and I don't recall having this issue. Will have to take a look at both UrlRewriteFilter and Nginx config files to expand on this.
I found that this (thanks to answer in here: Spring redirect url issue when behind Zuul proxy) seems to work as required (but is considered a 'workaround'):
#RequestMapping(value="/do-login", method = RequestMethod.POST)
public void doLogin (#ModelAttribute("authEntity") final AuthEntity authEntity,
final Model model,
HttpServletResponse servletResponse) throws IOException {
...
String rUrl = ServletUriComponentsBuilder.fromCurrentContextPath().path("/").build().toUriString();
servletResponse.sendRedirect(rUrl);
}

what's different between servlet url path and parameter?

What's the difference between localhost/user/user123, localhost/user?user=user123 and localhost/?user=user123?
How to get the parameter user123 from a URL localhost/user/user123 in servlet?
Thanks in advance
You can parse from the getPathInfo() of HttpServletRequest Object.
sample code
String urlPath = request.getPathInfo();
System.out.println("" + urlPath.substring(urlPath.lastIndexOf("/"), urlPath.length()- 1));
localhost/user/user123 looks like a RESTful way to identify a resource.
The two others aren't, I think.
These all are accessible from Servlet API. Check HttpServletRequest, you can access all information from there.
The actual values may differ how your webapp was deployed, but usually
localhost is the Context Path
the String after that is the Servlet PAth
the parameters after the ? is the Query String - you have to parse it, if you want to use
Generally you pass parameters like
/localhost/Servlet?parameter1=one
or for a JSP
/localhost/mypage.jsp?parameter1=one
In a servlet you can access the parameters by using the request object. So generally like this:
String parameter1 = request.getParameter("parameter1");
Here is some detail on getParameter for HttpServletRequest
Hope this helps.
localhost/user/user123 - this url will be handled by pattern /user/user123
localhost/user?user=user123 - this url will be handled by pattern /user, with user parameter set to user123 (for GET request)
localhost/?user=user123 - this url will be handled by pattern / with user parameter set to user123 (again, for GET)
I don't know how to retrieve user123 from url localhost/user/user123 with pure servlets, but it's pretty easy with web MVC frameworks. Spring example:
#Controller
#RequestMapping("/user")
public class Controller {
#RequestMapping(value = "/{user}")
public String getUser((#PathVariable String user) {
//here variable "user" is available and set to "user123" in your case
}
}

Spring mvc rewrite url "myapp.com/Foo/12345/test-one" to "myapp.com/Foo/12345/test-one-a-b"

I want to use a normal spring mvc controler and request mapping using path variables.
I do not want to forward or redirect, just change the string that user sees.
#RequestMapping(value = "/Foo/{id}/*", method = RequestMethod.GET)
public ModelAndView getFoo(#PathVariable final String friendlyUrl) {
//how can I rewite the url that user sees ?
}
(the same behaviour as when you change the title of an existing question on stackoverflow)
If you watch the traffic in wireshark, firebug or something you see, that stackoverflow sends a HTTP 301 Moved Permanently to the final URL.
You could do the same.
For this you need the HttpServletResponse, you can add it to the method signature to get it injected.
Set the permanent redirect:
String rightUrl = urlCompleter.complete(friendlyUrl);
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", rightUrl);
Where you need to implement urlCompleter on your own, eg. look in the database table of entries and locate the right url component.

Protocol redirection upon RenderRequest

I'm working on a project that uses the Spring Portlet-MVC framework and Velocity on a Liferay Portal server. For a few pages we have the requirement to serve them on a secure connection. Being fairly new to Portlets I came up with the solution of linking to an Action-Method and redirecting from there.
#ActionMapping(params = "command=secureRedirect")
public void actionSecureRedirect(ActionRequest request, ActionResponse response) {
HttpServletRequest servletRequest = PortalUtil.getHttpServletRequest(request);
String absoluteUrl = servletRequest.getRequestURL().toString();
String[] urlComponents = StringUtils.split(absoluteUrl, '/');
StringBuffer redirectUrl = new StringBuffer("https://");
redirectUrl.append(urlComponents[1]);
redirectUrl.append("<specificPath>");
response.sendRedirect(redirectUrl.toString());
}
My solution works but to me it doesn't seem really nice. I was wondering if somebody could think of another, more transparent way to do this (using Interceptors and Annotations on RenderMappings maybe?).
Any suggestions will be greatly appreciated!
By some pages, do you mean Liferay pages or are you just concerned about the url that gets generated when a user clicks on some link from the portlet.
If you want to make some link of the portlet secure, then when use liferay-portlet flavour or renderURL or actionURL. It has an attribute called secure, which if set to true will make your url starting with https
If you are looking for some liferay page(for example /web/guest/mypage) to be secure then its kind of a hack and I wouldnt really suggest this to anyone, but if you have got no other option, you can create a service pre hook and check for url patterns you are concerned about and redirect to an https version of that url.
write this code in controller
protected PortletURL getRedirectURL(ActionRequest actionRequest) {
ThemeDisplay themeDisplay = (ThemeDisplay) actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
String portletName = (String) actionRequest.getAttribute(WebKeys.PORTLET_ID);
PortletURL redirectURL = PortletURLFactoryUtil.create(PortalUtil.getHttpServletRequest(actionRequest), portletName, themeDisplay.getLayout().getPlid(),
PortletRequest.RENDER_PHASE);
return redirectURL;
}
#ActionMapping(params="something")
public void save(ActionRequest actionRequest, Other parameters){
/.....Your code
.....//
redirectURL = getRedirectURL(actionRequest);
actionResponse.sendRedirect(redirectURL.toString());
}

How to find the base URL of the current webapp in Spring?

I'd like to find the absolute URL of the webapp in Spring, from the Controller. I'm aware of JSTL c:url, but I need this info from inside the Controller.
#Controller
public class AuthorizeController {
#Autowired
private Authorizer auth;
#RequestMapping("/auth")
public String sendToAuthorization() {
String baseUrl = "http://localhost:8080/tasks/";
return "redirect:" + auth.getAuthorizationUrl(baseUrl);
}
}
As you can see the baseUrl is hardcoded, and I could provide it to the Authorizer class via Spring configuration, but I am sure that it's possible to get this information from Spring within the Controller. I tried to google "spring mvc url" and could not find a way to solve this problem.
I think that getting absolute url is only possible while processing the request as your server may have many IP addresses and domain names.
#RequestMapping("/auth")
public String sendToAuthorization(HttpServletRequest request) {
String baseUrl = String.format("%s://%s:%d/tasks/",request.getScheme(), request.getServerName(), request.getServerPort());
return "redirect:" + auth.getAuthorizationUrl(baseUrl);
}
As for the servlet, it may also have several mappings in web.xml.
similar question
P.S. Anyway, url parsing in runtime does not look like a good idea to me.
Very late to this answer, but a variant to Boris's answer, if you don't want to push servlet objects into method signatures, is to use RequestContextHolder from a utility class/method. This would also give the ability to abstract fallback logic (e.g., pulling from a property file). Cheesy example:
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(null != requestAttributes && requestAttributes instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
// build URL from request
}
else {
// fallback logic if request won't work...
}
This presumes you have org.springframework.web.context.request.RequestContextListener registered as a listener in web.xml

Categories

Resources