Struts2 - how to generate internationalized url's? - java

I have an application that needs to redirect to several internationalized urls, ie
www.mydomain.com/us/myapp/xxx.action
www.mydomain.com/fi/myapp/xxx.action
dwww.mydomain.com/de/myapp/xxx.action
We have a proxy server where the url is mapped to myapp/xxx.action?country=us and redirected to the application server. The problem is how to redirect to the next action with the format above?
Now the url for the next action is generated by using country from url and adding context path and action name and opened by javascript in jsp.
Example:
<body onload="javascript:top.location='${generatedPath}';return true;"></body>
Example form submit:
<s:form id="form" action="%{generatedPath}" theme="simple" method="post" includeContext="false">
Would like to do this in a less hackish way, and have tested a bit with struts.xml and type redirectAction, but cannot seem to be able to generate the url above, with the country before context path.
I have not found any struts2 documentation describing this, but are unsure if im looking at the right place as well? Should this be handled elsewhere?

I think the following discussion can help you:
How to do dynamic URL redirects in Struts 2?
Here, your result will look like:
<result name="redirect" type="redirect">${url}</result>
And, the action would be:
private String url;
private String country;
public void setCountry(String country) {
this.country = country;
}
public String getUrl()
{
return url;
}
public String execute()
{
url = "www.mydomain.com/" + country + "/myapp/xxx.action";
return "redirect";
}

Related

How can you build an absolute URL in thymeleaf?

I would like to display an absolute url generated at run-time with a parameter. Not create a href to a page but display the URL using th:text. Any simple way to do this with Tymeleaf (without having to concatenate the URL pieces from #request object and without using some MVC utility class)?
Attempt 1
<p th:text="#{/myServlet(myParam=${dynamicParameter})}" /> - only displays part of the URL leaving out the protocol, port and host name. I am getting /myServlet?myParam=123. The same behavior as for th:href, if you inspect the <a> you will see the same href - in that case the browser helps by inferring the protocol, port and so on
Attempt 2
th:text="#{__${#httpServletRequest.requestURI}__}" - produces a relative URI of the current page that doesn't include the protocol and so on
Attempt 3
th:text="#{__${#httpServletRequest.requestURL}__}" - produces this time an absolute URL of the current page containing the protocol, host and servlet context. The problem now is when I display this text from a different page, my URL is ...myApp/myOtherServlet so I need to edit this string to replace myOtherServlet with the URI I want.
Non Tymeleaf Attempt 1
#Service("urlUtils")
public class UrlUtilsServiceImpl implements UrlUtilsService {
#Override
public String getAbsoluteUrlTo(final String aPath, final String param, final String value){
return ServletUriComponentsBuilder
.fromCurrentContextPath()
.path(aPath)
.queryParam(param, value)
.build().toString();
}
}
page.html:
th:text="${#urlUtils.getAbsoluteUrlTo('/myServlet', 'myParam', ${dynamicParameter})}"
The problem is the host name that can be aliased before it reaches my server (see this).
Thymeleaf+JS Sollution
Using some java script plus thymeleaf
<p id="myUrl" th:text="#{/myServlet(myParam=${dynamicParameter})}" />
<script type="text/javascript">
$(document).ready(function () {
var myUrl= $("#myUrl");
myUrl.text(window.location.origin + myUrl.text());
});
</script>
You can concatenate servlet request on the fly:
th:text="${#httpServletRequest.scheme}+'://'+${#httpServletRequest.serverName}+':'+${#httpServletRequest.serverPort}+#{/myServlet(myParam=${dynamicParameter})}"
Or for JavaScript:
<script type="text/javascript">
GLOBAL.serverURI = '[[${#httpServletRequest.scheme}+'://'+${#httpServletRequest.serverName}+':'+${#httpServletRequest.serverPort}+#{/myServlet(myParam=${dynamicParameter})}]]';
</script>

How to send values from inputs to AutoLogin class in Liferay

I am developing a LinkedIn login hook following this example but I got stuck at passing parameters from my .jsp file to the .java class implementing AutoLogin.
If I write a portlet, the values are sent correctly to a processAction method, however here the same approach is not working.
In my linkedin.jsp file i have the following (simplified) structure.
<%
PortletURL linkedInRegiserURL = renderResponse.createActionURL();
linkedInRegiserURL.setParameter(ActionRequest.ACTION_NAME, "linkedInRegister");
%>
<form id="linkedInForm" action="<%= linkedInRegiserURL.toString() %>" method="post"
name='<portlet:namespace/>linkedInForm'>
<input type="hidden" name='<portlet:namespace/>email' id="email" />
</form>
And then inside a javascript method, based on the LinkedIn API, I populate my input and then submit the form.
document.getElementById('email').value = member.emailAddress;
document.getElementById('linkedInForm').submit();
Everything is fine here. The problems start inside the login() function in my LoginHook implements AutoLogin class. If I do a print test, the following results are shown:
#Override
public String[] login(HttpServletRequest request,
HttpServletResponse response) throws AutoLoginException {
String email1 = ParamUtil.getString(request, "email");
String email2 = request.getParameter("email");
String email3 = request.getAttribute("email").toString();
System.out.println("email1 : " + email1); //empty value
System.out.println("email2 : " + email2); //null
System.out.println("email3 : " + email3); //null
//etc.
}
I guess that the problems start here <form id="linkedInForm" action="<%= linkedInRegiserURL.toString() %>", but I am not sure and I don't know how should I pass my email parameter.
PS: I am working with Liferay 5.2.3, so writing a class extending BaseStrutsPortletAction is out of the question.
Params Inside login hooks in Liferay are a bit tricky, you can try 2 things:
Use the following function to retrive the "real" request wich may contains your parameter (Although I´´m not really sure if it´s available in liferay 5.2.3, in Liferay 6 its works):
PortalUtil.getOriginalServletRequest((javax.servlet.http.HttpServletRequest request)
Try with a GET call , instead a POST.
Another way to do it is to save the email as a cookie( in javascript) and then recover it in the autologin hook.
Hope it do some help...

Java Play2 with CDN

I am using a CDN (amazon cloudfront) and I am trying to configure play to work with a CDN
GET xxxxxxxxx.cloudfront.net/*file controllers.Assets.at(path="",file)
The problem with this approach is that my image url looks like this
http://localhost:9000/xxxxxxxxxxxxxxx.cloudfront.net/images/Ascalon_Wall_Ruins.jpg
I would need to remove the http://localhost:9000/
Any ideas how I can do this?
You don't need to use Play's router for building external links, instead you can just prefix it with domain, ie. if you're storing paths in your model as images/Ascalon_Wall_Ruins.jpg in its file field, you can just put it directly in template:
#for(item <- itemsList){
<img src="http://domain.tld/#item.file" />
}
Of course you can also create additional method in your model's class to deliver ready-to-use path.
I solved my problem like this:
package Config;
public class CDN {
private final static String url = "http://yourcdnurl.net/;
public static String createUrl(String s) {
return url + s;
}
}
usage:
<link rel="stylesheet" media="screen" href= "#Config.CDN.createUrl("stylesheets/bootstrap.css")">

JSP Validating and Redirecting: how to validate form input and forward the errors back to the original page?

I'm taking a class on JSP and I have an assignment... we have to write a JSP page that takes user input, validate the input and then forward it to a different web site. To be more precise, we were asked to implement a rudimentary version of the FareFinder functionality of Amtrak's web site.
There are 2 main purposes to this assignment:
(a) to write JSP which performs as middleware;
and (b) to write JSP which validates form data.
I have a general question about the principles of doing the validation. Currently I have a JSP that has a form and a submit button. When the user clicks on the submit button I forward them to Validate.jsp. The Validate.jsp will then validate the data and if the input is OK it will automatically redirect the request to the Amtrak web site with all the parameters filled out.
FareFinder.jsp -> Validate.jsp -> Amtrak
(click on the file name to see all my code in a pastie)
Briefly, the main thing that I'm doing FareFinder.jsp:
<FORM METHOD=POST ACTION="Validate.jsp">
<!-- all the input fields are up here -->
<P><INPUT TYPE=SUBMIT></P>
</FORM>
The main thing I'm doing in Validate.jsp:
<%# page import="java.util.*" import="java.io.*"%>
<%
// retreive all the parameters
String origin = request.getParameter("_origin");
String depmonthyear = request.getParameter("_depmonthyear");
String depday = request.getParameter("_depday");
String dephourmin = request.getParameter("_dephourmin");
String destination = request.getParameter("_destination");
String retmonthyear = request.getParameter("_retmonthyear");
String retday = request.getParameter("_retday");
String rethourmin = request.getParameter("_rethourmin");
String adults = request.getParameter("_adults");
String children = request.getParameter("_children");
String infants = request.getParameter("_infants");
String searchBy = request.getParameter("_searchBy");
// validate the data
// redirect to Amtrak or back to FareFinder.jsp
%>
I have several questions:
How do I return to FareFinder.jsp from Validate.jsp and reflect the errors found in the validation page?
Once I have found errors- do I redirect the response back to FareFinder.jsp?
How could I transmit the error(s) back to FareFinder.jsp?
A generic answer would be fine too, but I'm giving my code as an example.
Note: the validation must be performed on the server side and I can't use javascript.
OK, as per the comments, Servlets are covered as well. Now, create one and implement doPost() like follows (semi pseudo):
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> errors = new HashMap<String, String>();
String origin = request.getParameter("origin");
if (origin does not validate) {
errors.put("origin", "Put error message here.");
}
// Repeat for all parameters.
if (errors.isEmpty()) {
// No errors, redirect to Amtrak.
response.sendRedirect("http://amtrak.com");
} else {
// Put errors in request scope and forward back to JSP.
request.setAttribute("errors", errors);
request.getRequestDispatcher("FareFinder.jsp").forward(request, response);
}
}
Map this servlet in web.xml on an url-pattern of /validateFare so that you can invoke it by http://example.com/context/validateFare.
Now do in JSP something like:
<form action="validateFare" method="post">
<label for="origin">Origin</label>
<input id="origin" name="origin" value="${param.origin}">
<span class="error">${errors.origin}</span>
<!-- Repeat other fields here. -->
</form>
You see that the form action already points to the servlet. The ${param.origin} in input values will retain the submitted value by doing request.getParameter("origin") under the hoods. The ${errors.origin} will show any associated error message by roughly doing pageContext.findAttribute("errors").get("origin").
This must get you started :) Good luck.

Retaining the submitted JSP form data

I am having a web form(JSP) which submits the data to different application, hosted on different server. After submitting the form data, that application redirect back to same JSP page. Now, I want to save the entered the data. What are the different approaches to retain the submitted data in web form. I would not prefer to store the data in DB or any file.
PS: I would like to retain the submitted form data when request again redirected to same JSP page. Therefore, user need not to re-enter the data. Like, data can be stored in Session or Request etc.
Best what you can do is to submit to your own servlet which in turn fires another request to the external webapplication in the background with little help of java.net.URLConnection. Finally just post back to the result page within the same request, so that you can just access request parameters by EL. There's an implicit EL variable ${param} which gives you access to the request parameters like a Map wherein the parameter name is the key.
So with the following form
<form action="myservlet" method="post">
<input type="text" name="foo">
<input type="text" name="bar">
<input type="submit">
</form>
and roughly the following servlet method
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
String foo = request.getParameter("foo");
String bar = request.getParameter("bar");
String url = "http://external.com/someapp";
String charset = "UTF-8";
String query = String.format("foo=%s&bar=%s", URLEncoder.encode(foo, charset), URLEncoder.encode(bar, charset));
URLConnection connection = new URL(url).openConnection();
connection.setUseCaches(false);
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("accept-charset", charset);
connection.setRequestProperty("content-type", "application/x-www-form-urlencoded;charset=" + charset);
try (OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), charset)) {
writer.write(query);
}
InputStream result = connection.getInputStream();
// Do something with result here? Check if it returned OK response?
// Now forward to the JSP.
request.getRequestDispatcher("result.jsp").forward(request, response);
}
you should be able to access the input in result.jsp as follows
<p>Foo: <c:out value="${param.foo}" /></p>
<p>Bar: <c:out value="${param.bar}" /></p>
Simple as that. No need for jsp:useBean and/or nasty scriptlets.
In JSP this kind of thing is usually handled by using a javabean to store the form values and then using the jsp:useBean tag. For example you would create the following javabean:
package com.mycompany;
public class FormBean {
private String var1;
private String var2;
public void setVar1(String var) { this.var1 = var; }
public String getVar1() { return this.var1; }
public void setVar2(String var) { this.var2 = var; }
public String getVar2() { return this.var2; }
}
In your form jsp you'd use the useBean tag and your form fields values would get their values from the bean:
<jsp:useBean id="formBean" class="com.mycompany.FormBean" scope="session"/>
...
...
<input type="text" name="var1" value="<%=formBean.getVar1()%>" />
In your jsp the form data is posted to (then redirects back) you'd have the following code that would push the posted form data into the bean.
<jsp:useBean id="formBean" class="com.mycompany.FormBean" scope="session"/>
<jsp:setProperty name="formBean" property="*"/>
Another option is to just stuff the form data into the session in your save page:
String var1 = request.getParameter("var1");
String var2 = request.getParameter("var2");
session.setAttribute("var1", val1);
session.setAttribute("var2", val2);
...
and reference it in your form (null checking omitted):
<input type="text" name="var1" value="<%= session.getAttribute("var1") %>" />
If I understand the problem correctly (big "if" there), you have a FORM that has a method of POST and an ACTION that is pointed directly to a remote server. When the user clicks "Submit" the browser isn't involving your host in that transaction, the data is going to the "ACTION" recipient. That would make your options limited to implementing a call back relationship with the remote service (possibly beyond your control), setting up a local proxy servlet to intercept the data and forward the POST along to it's intended recipient (which would make the POST originate from the server and not the client (this could likely cause problems)), or utilize some AJAX design pattern to send the form data to two places instead of just one which the FORM tag dictates.
Beyond that, you would need to have some form of local persistence like a database or a file.
Did I help at all?

Categories

Resources