I'm trying to retrieve a post value from a hook on the same page so when i value is right, content will appear.
I added this code in the hook to have it on the specified page.
<portlet:actionURL secure="<%= PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS || request.isSecure() %>" var="SecondloginURL">
<portlet:param name="saveLastPath" value="0" />
<portlet:param name="struts_action" value="/journal_content/view" />
</portlet:actionURL>
<aui:form action="" name="auth" method="POST">
<aui:input label="Second Password" type="password" name="password" />
<aui:button type="submit" value="authenticate" />
</aui:form>
I managed to retrieve the value but when it's validated session started but it doesn't move cross-pages.
Here is the code:
<% String pass = request.getParameter("password"); %>
<c:if test="<%= pass.equals(\"1234\") %>">
<%
HttpSession session1 = request.getSession();
session1.setAttribute("pass","authenticated");
String foo = (String) session1.getAttribute("pass");
out.println(foo);
%>
<h2>this is the second password and it's working</h2>
<div class="journal-content-article" id="article_<%= articleDisplay.getCompanyId() %>_<%= articleDisplay.getGroupId() %>_<%= articleDisplay.getArticleId() %>_<%= articleDisplay.getVersion() %>">
<%= RuntimePortletUtil.processXML(application, request, response, renderRequest, renderResponse, articleDisplay.getContent()) %>
</div>
</c:if>
In a Liferay hook you can override stock Liferay jsps, thus also add forms.
You can also override Liferay Actions and other Liferay classes. You don't make clear where you put the above code and what else you have in your hook, neither what you are trying to achieve.
First: You should direct your form to some <portlet:actionURL/> and then, depending on the portlet this jsp is invoked from, you'll have to implement or override the action handler for that portlet. In there you'll be able to get the parameter value from the ActionRequest
Related
I'm making a form to add events to a list but I need to be able to see in that form the previous events from that list. I have a jsp that shows a list of events but it takes an attribute usually added by the controller when you access the list directly from the browser.
So how can I add the list jsp filling that attribute so it shows a list and not just the headers?
I have alreay included the jsp using
<jsp:include page="comp_list.jsp"></jsp:include>
And it shows the headers but as there is no attribute it shows no list. I tried adding attributes to the include like:
<jsp:include page="comp_list.jsp">
<jsp:attribute name="compensaciones">
${compensaciones}
</jsp:attribute>
</jsp:include>
But when I do it it shows an error telling me that this cannot be done.
Also tried params but that would not be the answer for me because params are treated in the controller and not in the jsp itself.
I'm just getting the header of the list which is fine, but i would like to see the list.
Edit: this is how i build the list in case you are wondering
<tbody>
<c:forEach var="comp" items="${compensaciones}">
<td>${comp.getSomething()}</td>
...
</c:forEach>
</tbody>
<jsp:include page="pagename.jsp" />
i thing you are not provide extension in your include tag
Sometimes since I've had prior experience back in the days with HTML and PHP, we simply just would include things like navigation and header for easier management.
I'm unsure for what purpose you're including JSP, but here's an example of how I've done it since I include JSP if a boolean is true.
The site that is accessed:
<div class="row">
<div class="col-lg-2">
</div>
<div class="col-lg-8">
<%
if (loggedin) {
%>
<%# include file="includes/profile.jsp" %>
<% } else {
out.println("<div><h2>You aren't logged in!</h2></div>");
}
%>
</div>
<div class="col-lg-2">
</div>
</div>
And the top and bottom of the JSP file I'm including doesn't contain things like head, title, html, body etc.
<%
User currUser = null;
currUser = (User) session.getAttribute("user");
%>
<div>
<h2>Du er logget ind, velkommen <% out.println(currUser.getUsername().toUpperCase()); %></h2> <br>
<h5>Din Saldo: <b><% if (currUser.getBalance() < 0) { out.println("<font color='red'>" + currUser.getBalance() + "</font>");} else { out.println("<font color='green'>" + currUser.getBalance() + "</font>");} %></b></h5>
<br>
<form class="form" method="post" action="#">
<h4>Oplysninger: </h4>
<h6>
For at ændre oplysninger skal du indtaste dit kodeord!
</h6>
Nuværende Kode: <input type="password" class="form-control" placeholder="kodeord" name="password" required>
<hr>
Email: <input type="text" class="form-control" value="<% out.println(currUser.getEmail()); %>" name="email"> <br>
Brugernavn: <input type="text" class="form-control" value="<% out.println(currUser.getUsername()); %>" name="username"> <br>
<input type="submit" class="btn btn-default" value="Indsend Oplysninger" />
</form>
</div>
When importing JSP into JSP, it's important to know that they will conflict if 1. Duplicate Local Variables. 2. Certain HTML tags aren't correct.
Your intended use seems very complicated to me since I'm not quite understanding it, sorry :3 but if you can't get it working consider to throw it to a session and if it's a one time use then remove it once you used it.
This is working from dacades
<%# include file="../scripts/standard_head_declaration.jsp" %>
I am trying to figure out the best way to dynamically change some page html on my page using ajax and struts2. I have these tag files containing the jsp of the html that needs to be changed. I want to use these tag files for the ajax calls and not have to copy the html from them into some other source and worry about populating the data into that html, because the JSP already handles that.
So what I am doing is making a Jquery Ajax call to a jsp that simply includes the tag file I want the updated html for, and in that tag file, I am making a call to the struts2 action with the <s:action /> tag. What I want, and what I think would be proper is if I could have that action execute, and all the struts2 jsp tags below would use the data from that action class that was executed. So for example, if I have <s:fielderror /> tags latter on in the jsp, the field errors that were added in the action that was executed with the action tag, would be rendered in the same jsp by this fielderror tag. Here is an example of what I am trying to do.
tag file in question:
<%# tag language="java" pageEncoding="UTF-8"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="s" uri="/struts-tags" %>
<%-- This is the action that I want to execute and use for the rest of the jsp in this file --%>
<s:action name="ajaxRegister" namespace="/actions" />
<form id="register_form" action="register/" method="post">
<c:choose>
<c:when test="${not empty sessionScope.username}">
<div class="inputs">
<h1>Create Your Password</h1>
<label style="padding-bottom: 10px;">Create your password to finish your registration</label>
<label for="password1">Password:</label>
<input type="password" name="password1" id="register_pwd_1" data-enter-click="finish_button" />
<label for="password2">Verify Password:</label>
<input type="password" name="password2" id="register_pwd_2" data-enter-click="finish_button" />
<input name="noScript" type="hidden" value="${pageContext.request.servletPath}" data-no-script />
<div id="register_error" class="response">
<s:fielderror fieldName="register.error" />
</div>
<div class="clear"></div>
</div>
<input type="submit" id="finish_button" value="Finish" />
</c:when>
<c:otherwise>
<div class="inputs">
<h1>Not a member yet? Sign Up!</h1>
<input name="uuid" type="text" data-no-script />
<div id="paste_input"></div>
<input name="noScript" type="hidden" value="${pageContext.request.servletPath}" data-no-script />
<div id="register_error" class="response">
<s:fielderror fieldName="register.error" />
</div>
</div>
<input type="submit" id="register_button" value="Register" />
</c:otherwise>
</c:choose>
</form>
My problem is that even though the first thing I do in this jsp is calling the action, the fielderror tags do not populate the html with the field errors that are generated in the action class. Is this possible to do? Also, I have not been able to figure out how to pass parameters as the properties to be set in the action class. The parameters that the action class needs to use are the values of that registration form that the user submits. It is that submit button that calls this jsp to render a response for them. But if I cannot get those form values to the action, then there is no point.
Also, I am not using json for this because if the register process is completed, then a totally new part of the page needs to be dynamically added, so its not just simple error messages that I am returning to the user. And I do not want to have the html in strings in the java code, or javascript, or even somewhere else, because I already have it in the JSP.
Do I have the right idea?
I have a liferay portlet with a simple form for entering two numbers and submitting them to be added:
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%# taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<portlet:defineObjects />
<portlet:actionURL var="calculateURL">
<portlet:param name="mvcPath" value="/html/calculator/edit.jsp" />
</portlet:actionURL>
<aui:form action="<%= calculateURL %>" method="post">
<aui:input label="x" name="x" type="text" value="${x}"/>
<aui:input label="y" name="y" type="text" value="${y}"/>
<aui:button type="submit" value="add"/>
</aui:form>
This works fine. I would now like to add a button that allowed me to subtract the numbers instead. But when I add the new button, I don't know how to differentiate between which button was pressed, when I am in my processAction method. How can I do this?
Alternatively: I have found this answer on how to do it, but I wasn't able to get it to work. Does it point me in the right direction, and should I keep experimenting with the answer given there?
You can have two different action method in your controller class and in jsp based on which button clicked, call the action url accordingly. Find below code which changes form action based on the button clicked. This helps you keep your business on logic seperate in your controller class. Else you can have only action and then pass parameter to action to identify what to perfrom (add or subtract)
<portlet:actionURL var="subtractNumberURL">
</portlet:actionURL>
<portlet:actionURL var="addNumberURL">
<portlet:param name="mvcPath" value="/html/calculator/edit.jsp" />
</portlet:actionURL>
<script type="text/javascript" charset="utf-8">
function submitForm(action){
if(action==0){
A.one('<portlet:namespace/>form').set('action',"<%=addNumberURL%>");
}else{
A.one('<portlet:namespace/>form').set('action',"<%=subtractNumberURL%>");
}
}
</script>
<aui:form action="<%= addNumberURL%>" name="form" method="post">
<aui:input label="x" name="x" type="text" value="${x}"/>
<aui:input label="y" name="y" type="text" value="${y}"/>
<aui:button type="submit" value="add" onClick="submitForm(0)"/>
<aui:button type="submit" value="subtract" onClick="submitForm(1)"/>
</aui:form>
I've successfully implemented this way (tested on liferay 6.1.2 and FF).
I've found this article very useful!
Keep into account function name: must NOT be "submitForm"!
<aui:script use="aui-base">
Liferay.provide(window, 'mysubmitForm', function(action) {
if(action=='add'){
A.one('#<portlet:namespace/>form').set('action','<%=addNumberURL.toString()%>');
}else{
A.one('#<portlet:namespace/>form').set('action','<%=subtractNumberURL.toString()%>');
}
});
</aui:script>
Personally I prefer a clean and simple solution into javascript with just one input hidden on the HTML code and then in the action with a switch select the correct code to be executed.
I use Jquery but the code can be implemented on plain javascript as well:
Inside the form, we put a hidden variable like this:
<aui:input name="botonClicked" id="botonClicked" type="hidden"></aui:input>
We define then our buttons but with "type='button'", not with "type='submit'", for example:
<aui:button icon="icon-save" iconAlign="left" value="Save" type="button" cssClass="btn-primary buttonListener" name="Save"></aui:button>
<aui:button icon="icon-save" iconAlign="left" value="Send" type="button" cssClass="btn-primary buttonListener" name="Send"></aui:button>
And then with a simple jquery we put the button clicked on our hidden input and submit the form:
$(".buttonListener").click(function(){
var nombre = $(this).attr("name");
nombre = nombre.replace(namespace,'');
$("#botonClicked").val(nombre);
$("#OurForm").submit();
});
In your Java code, in the Action code, just we use a switch to know wich button was pressed and call our different functions:
String botonClicked= ParamUtil.getString(actionRequest, "botonClicked");
switch (botonClicked) {
case "Save":
Guardar(actionRequest, actionResponse);
break;
case "Send":
Enviar(actionRequest, actionResponse);
break;
default:
break;
}
For me at least this solution is cleaner and it works perfectly.
We are trying to use CAS server for SSO for our existing web based applications. Our goals are
Achive SSO across the various applications (including cross domain).
Have Customized login (In UI Terms) pages for different apps, when they are redirected to CAS Server login page.
Ability to do login without going to the CAS Login page, reason being "A small login
section" is embedded in the page itself and user will not be redirected to the CAS login page for better usability.
We are done with the first and second goal. But having problems with third one.
For this functionality we are trying to replicate the same actions as in second goal , only difference being submitting/posting the data
(credentials , login tickets etc) from non CAS login page.
We cannot use iframes to show the CAS login page in the small section , this is vulnerable to browser compatability issues.
We cannot use ajax to use CAS api's to getting the login ticket and doing the HTTP post (cross domain issue)
What we have done is : Retrieve the loginticket and execution id on the load of the non cas login page by doing an HTTP post on the server side.
when we post the username / password along with the loginticket and execId , the CAS server instead of accepting the post data
redirects the user to CAS login page but doing a browser back and submitting the data again works fine. Reasons
is no jsession extablished between the CAS and the browser and hence CAS rejects any post data. We can use the CAS restAPI but it will just login the user and no help in getting the SSO done.
Any thoughts on how can we handle this problem ??
Thanks,
Pratik
There is a wiki page on CAS which debates about that : https://wiki.jasig.org/display/CAS/Using+CAS+without+the+Login+Screen (but which is older than the google groups discussion proposed by Misagh M).
My solution is "Using CAS from external link or custom external form".
You must get a copy of CAS official client source code( cas-client-core, https://github.com/apereo/java-cas-client ), and make sure you could compile it.
You need change the doFilter() function code at org.jasig.cas.client.authentication.AuthenticationFilter in client source code like the below.
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpSession session = request.getSession(false);
final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
if(request.getServletPath().toLowerCase().equals("/caslogout.jsp"))
{
// Set the custom client login page when you logout from CAS server.
request.setAttribute("casServerLogoutUrl",casServerLoginUrl.replace("login","logout"));
request.setAttribute("customServerLoginUrl",customServerLoginUrl);
//We must remove the attribute of CONST_CAS_ASSERTION manually
if(session!=null)
session.removeAttribute(CONST_CAS_ASSERTION);
filterChain.doFilter(request, response);
return;
}
if (assertion != null) {
filterChain.doFilter(request, response);
return;
}
// Although the custom login page must called caslogin, here you can change it.
if(request.getServletPath().toLowerCase().equals("/caslogin.jsp"))
{
//Set the a default parameter to the caslogin
request.setAttribute("defaultServerIndexUrl",defaultServerIndexUrl);
request.setAttribute("casServerLoginUrl",casServerLoginUrl);
filterChain.doFilter(request, response);
return;
}
final String serviceUrl = constructServiceUrl(request, response);
final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
filterChain.doFilter(request, response);
return;
}
final String modifiedServiceUrl;
log.debug("no ticket and no assertion found");
if (this.gateway) {
log.debug("setting gateway attribute in session");
modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
} else {
modifiedServiceUrl = serviceUrl;
}
if (log.isDebugEnabled()) {
log.debug("Constructed service url: " + modifiedServiceUrl);
}
final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
if (log.isDebugEnabled()) {
log.debug("redirecting to \"" + urlToRedirectTo + "\"");
}
// Add a custom server login url parameter to the CAS login url.
response.sendRedirect(urlToRedirectTo+"&customLogin=custom&customLoginPage="+customServerLoginUrl);
Add your own compiled cas-client-core to the dependence of your client webapp.
Add the caslogin.jsp to your client webapp.
<form method="GET" action="<%=request.getAttribute("casServerLoginUrl")%>">
<p>Username : <input type="text" name="username" /></p>
<p>Password : <input type="password" name="password" /></p>
<p><input type="submit" value="Login" /></p>
<input type="hidden" name="auto" value="true" />
<input type="hidden" name="service" value="<%=request.getParameter("service")==null?request.getAttribute("defaultServerIndexUrl"):request.getParameter("service")%>" />
Edit the web.xml in client webapp. Add below code in the filter of CASFilter
<init-param>
<param-name>defaultServerIndexUrl</param-name>
<param-value>http://clientip:port/webappname/index.jsp</param-value>
</init-param>
<init-param>
<param-name>customServerLoginUrl</param-name>
<param-value>http://clientip:port/webappname/caslogin.jsp</param-value>
</init-param>
Edit the code at cas-server-webapp/WEB-INF/view/jsp/default/ui/casLoginView.jsp in CAS server web app.
<%
String auto=request.getParameter("auto");
String customLogin=request.getParameter("customLogin");
if(auto!=null&&auto.equals("true"))
{
%>
<html>
<head>
<script language="javascript">
function doAutoLogin()
{
document.forms[0].submit();
}
</script>
</head>
<body onload="doAutoLogin()">
<form id="credentials" method="POST" action="<%=request.getContextPath()%>/login?service=<%=request.getParameter("service")%>">
<input type="hidden" name="lt" value="${loginTicket}" />
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input type="hidden" name="username" value="<%=request.getParameter("username")%>" />
<input type="hidden" name="password" value="<%=request.getParameter("password")%>" />
<input type="hidden" name="login_form" value="<%=request.getParameter("login_form")%>" />
<input type="hidden" name="rememberMe" value="true" />
<input type="submit" value="Submit" style="visibility: hidden" />
</form>
</body>
</html>
<%
}
else if(customLogin!=null&&customLogin.equals("custom"))
{
response.sendRedirect(request.getParameter("customLoginPage")+"?service="+request.getParameter("service"));
%>
<%
}
else
{%>
<!-- The Orgin Source Code of casLoginView.jsp!!!!!!!!!!!!!!!!!!!!!!!!! -->
<%}%>
MAKE SURE you could login cas with caslogin.jsp.
Put the content of your own login page to the caslogin.jsp.
Now you could login cas with your own caslogin.jsp
I also make a sample about how to login cas with client custom login screen rather than server login srceen. You could download it on
https://github.com/yangminxing/cas-custom-login-page
I know its late but if someone is looking for an answer this is how I solve this. This is the code I put in casLoginView.jsp
<head>
<script language="javascript">
function doAutoLogin() {
document.forms[0].submit();
}
</script>
</head>
<body onload="doAutoLogin();">
<form id="credentials" method="POST" action="<%= request.getContextPath() %>/login?service=<%= request.getParameter("service") %>">
<input type="hidden" name="lt" value="${loginTicket}" />
<input type="hidden" name="execution" value="${flowExecutionKey}" />
<input type="hidden" name="_eventId" value="submit" />
<input type="hidden" name="serviceLogin" value="<%= request.getParameter("serviceLogin") %>"/>
<input type="hidden" name="username" value="<%= request.getParameter("username") %>" />
<input type="hidden" name="password" value="<%= request.getParameter("password") %>" />
<%
if ("true".equals(request.getParameter("rememberMe"))) {%>
<input type="hidden" name="rememberMe" id="rememberMe" value="true"/>
<% } %>
<input type="submit" value="Submit" style="visibility: hidden;" />
</form>
<% } else {
response.sendRedirect(request.getParameter("redirectURL"));
}
%>
</body>
And in your webapp just make a POST petition to your CAS server.
Hope it helps
to login cas without login screen page, I custom flow login (write another action-state)
1.In login-webflow.xml you write other action-state of transition in action-state id="generateLoginTicket". In this action-state (I call it is submitNotUseForm), I do the same "realSubmit" action-state.
2.In evaluate of "submitNotUseForm" --> class AuthenticationViaFormAction, I write method submitNotForm() and check :
2.1: if have no service call, it return value for call to "viewLoginForm"
else I get parameter from request set for credentials
2.2: Everything else do the same method submit
It work for me !
we tried to hit CAS and add &gateway=true in the URL param. CAS will redirect to our app's base_url/j_spring_cas_security_check without showing login prompt (our app used Spring with CAS)
I am trying to submit the text field value and print it using the servlet. The index.jsp is my main page and I am using jsp:include to include the form which reside in another page which is login.html.
here is the code i have for login.html
<form id="f1" action="ControllerServlet" method="GET">
<p>username
<input class ="text-input" type="text" id="txtusername" />
</p>
<p>
<input type="submit" value="submit" />
</p>
the index.jsp
<div id="col3_content" class="clearfix">
<h1>H1 Heading</h1>
<jsp:include page="login.html"></jsp:include>
</div>
the controller servlet
String usrname = request.getParameter("txtusername").toString();
out.print(usrname);
The problem is this is throwing a null pointer exception. what am I doing wrong here ? any help appreciated. thanks
Please use name not id
<input class ="text-input" type="text" name="txtusername" />
The id is not used to identify the name of the input parameter. The right attribute for the parameter is name, currently you are using an input without a name. So use
<input class ="text-input" type="text" name="txtusername" id="txtusername" />
You need to define name attribute of input tag to get it in Servlet by name.
<input class ="text-input" type="text" id="txtusername" name="txtusername" />
Also make sure you are writing code in doGet or service method of servlet as you have GET as action in form tag.
Code for Login.html
<form action="ControllerServlet" method="GET">
<p>username :
<input type ="text" name="txtusername" /></p>
<p><input type="submit" value="submit" /> </p>
</form>
ControllerServlet.java
public void service(ServletRequest request, ServletResponse response)
{
String username = request.getParameter("txtusername");
PrintWriter out = response.getWriter();
out.println("User Name " + username)
I faced a similar situation, when I checked front end, the form seems to have all the value populated correctly. However, after form.submit, from server side using request.getParameter("the parameter") does not return the value populated. After tuning on the network traffic tab in browser, I see the parameter was there, but there was a typo.
Hopefully could save you some time if same thing happens to you.