jsp code to upload jgp files and save in mysql db - jsp-tags

This is my servlet code
package classes;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
#WebServlet("/FileUploadDBServlet")
#MultipartConfig(maxFileSize = 16177215) // upload file's size up to 16MB
public class FileUploadDBServlet extends HttpServlet {
// database connection settings
private String dbURL = "jdbc:mysql://localhost:3306/studreg";
private String dbUser = "root";
private String dbPass = "";
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// gets values of text fields
String matric = request.getParameter("matric");
//String lastName = request.getParameter("lastName");
InputStream inputStream = null; // input stream of the upload file
// obtains the upload file part in this multipart request
Part filePart = request.getPart("photo");
if (filePart != null) {
// prints out some information for debugging
System.out.println(filePart.getName());
System.out.println(filePart.getSize());
System.out.println(filePart.getContentType());
// obtains input stream of the upload file
inputStream = filePart.getInputStream();
}
Connection conn = null; // connection to the database
String message = null; // message will be sent back to client
try {
// connects to the database
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// constructs SQL statement
String sql = "INSERT INTO contacts (matric, photo) values (?,?)";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, matric);
//statement.setString(2, lastName);
if (inputStream != null) {
// fetches input stream of the upload file for the blob column
statement.setBlob(2, inputStream);
//statement.setBlob(3, inputStream);
}
// sends the statement to the database server
int row = statement.executeUpdate();
if (row > 0) {
message = "File uploaded and saved for transcript processing";
}
} catch (SQLException ex) {
message = "ERROR: " + ex.getMessage();
ex.printStackTrace();
} finally {
if (conn != null) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
// sets the message in request scope
request.setAttribute("Message", message);
// forwards to the message page
getServletContext().getRequestDispatcher("/message.jsp").forward(request, response);
}
}
}
This is my jsp code
<%# page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*" errorPage="" %>
<%# page import ="java.sql.*" %>
<%#page import="classes.DbConn2"%>
<%#page import="classes.FileUploadDBServlet"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<form method ="post" action ="receipt.jsp" name="form1">
<p>
<input type="hidden" name="matric" value="<%=matric %>">
<td colspan="2"> <input name="invoiceno" type="hidden" value="<%=invoiceno%>" />
<input type="submit" value="Print Payment Receipt">
</p>
<p> </p>
</form>
<left>
<p>Click here to print <a target="_blank "href="http://www.collegesch.com/reg/receipt.jsp?matric=<%=matric%>&invoiceno=<%=invoiceno%>">Receipt</a>
<h1 align="left">File Upload for Transcript Request</h1>
<form method="post" action="FileUploadDBServlet" name="form2" enctype="multipart/form-data">
<table width="759" border="0">
<td colspan="2"> <input name="matric" type="hidden" value="<%=matric%>" />
<tr>
<td><p>Picture( jpeg, 450X500): </p>
</td>
<td><input type="file" name="photo" size="10"/></td>
<td><p>Result( jpeg, 450X500): </p>
</td>
<td><input type="file" name="photo1" size="10"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save">
</td>
</tr>
</table>
<p> </p>
</form>
</center>
 <br /> </td>
<td> </td>
</tr>
<tr>
<td width="4"> <br />
<br /> </td>
<td width="35"> </td>
<td width="505"> </td>
<td width="547"> </td>
</tr>
</table>
</body>
</html>
But after uploading a file, I get this error:
The requested URL /reg/FileUploadDBServlet was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

Change
action="FileUploadDBServlet"
To
action="<%= request.getContextPath () %>/FileUploadDBServlet"
and try again - the relative path was probably not found under the path.

Related

ASP.NET Core MVC - How to display data from Excel into HTML table before inserting into the DB

In ASP.NET Core-6 MVC, I have excel file (student.xlsx) with this code:
Model:
public class Students
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int AdmissionYear { get; set; }
public string RegistrationNo { get; set; }
}
Controller:
public async Task<IActionResult> Upload(IFormFile file)
{
if (file == null)
{
return RedirectToAction(nameof(Index));
}
List<Students> studentList = new List<Student>();
using(var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream).ConfigureAwait(false);
using(var package = new ExcelPackage(memoryStream))
{
var worksheet = package.Workbook.Worksheets[0];
if (worksheet.Dimension.Rows > 0 && worksheet.Dimension.Columns > 0)
{
for (int row = 2; row <= worksheet.Dimension.Rows; row++) // start at row 2 to skip header
{
Students student = new Students();
student.FirstName = worksheet.Cells[row, 1].Value.ToString();
student.LastName = worksheet.Cells[row, 2].Value.ToString();
student.AdmissionYear = int.Parse(worksheet.Cells[row, 3].Value.ToString());
student.RegistrationNo = worksheet.Cells[row, 4].Value.ToString();
studentList.Add(student);
}
}
}
}
return View("Index", studentList);
}
View:
<div class="form-group">
<label name-for="file">Excel xlsx Upload</label>
<input type="file" name="file" />
</div>
<input type="button" name="display" value="Show Data" id="btnShow" class="btn btn-primary" />
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th class="table-head">
<input type="checkbox" onchange="checkAll(this)" name="chk[]" />
</th>
<th>First Name</th>
<th>Last Name</th>
<th>AdmissionYear</th>
<th>RegistrationNo</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="middle" align="center" style="width: 2%;">
<input type="checkbox" onchange="checkSingle(this)" name="chk[]" />
</td>
<td></td>
<td></td>
<td> </td>
<td></td>
</tr>
</tbody>
</table>
As soon as the user choose the excel file to be uploaded, when he clicks on choose file, and clicks on Show Data, it should display the excel data in the table in html without even the submit upload button
I want to first display the imported data into HTML table in the view page before the user then submits and insert into the DB.
How do I achieve this?
Thanks
You can use JavaScript to monitor the status of the file, then read the file and load it through xlsx.full.
You can refer to my test code below:
<div class="container">
<h2 class="text-center mt-4 mb-4">Convert Excel to HTML Table using JavaScript</h2>
<div class="card">
<div class="card-header"><b>Select Excel File</b></div>
<div class="card-body">
<input type="file" name="file" id="excel_file" />
<input type="button" name="display" value="Show Data" id="btnShow" onclick="ShowData()" class="btn btn-primary" />
</div>
</div>
<div id="excel_data" class="mt-5"></div>
</div>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonyous" />
<script type="text/javascript" src="https://unpkg.com/xlsx#0.15.1/dist/xlsx.full.min.js"></script>
<script>
var table_output = "";
var excel_file = document.getElementById("excel_file");
excel_file.addEventListener("change",(event) =>{
var reader = new FileReader();
reader.readAsArrayBuffer(event.target.files[0]);
reader.onload = function(event){
var data = new Uint8Array(reader.result);
var work_book = XLSX.read(data,{type:'array'});
var sheet_name = work_book.SheetNames;
var sheet_data = XLSX.utils.sheet_to_json(work_book.Sheets[sheet_name[0]],{hearder:1});
if(sheet_data.length > 0)
{
table_output += '<table class="table table-striped table-bordered">';
table_output += '<thead><tr><th>First Name </th><th> Last Name </th><th> AdmissionYear </th><th> RegistrationNo </th></tr></thead>';
table_output += '<tbody>';
for(var row = 0; row < sheet_data.length; row++)
{
table_output += '<tr>';
table_output += '<td>' + sheet_data[row].FirstName + '</td>';
table_output += '<td>' + sheet_data[row].LastName + '</td>';
table_output += '<td>' + sheet_data[row].AdmissionYear + '</td>';
table_output += '<td>' + sheet_data[row].RegistrationNo + '</td>';
table_output += '</tr>';
}
table_output += '</tbody></table>';
}
}
})
function ShowData()
{
document.getElementById("excel_data").innerHTML = table_output;
}
</script>
Test Result:
When file is selected and ShowData is clicked:
Hope this can help you.
You can import the Sheetjs library which can read your excel file and render it to a table. Demo
The library can read your data into Json, you can modify that Json to add an empty column and then hook into the render event to render the checkbox.

when server's down, datas on board table disappear in Liferay

i'm on 7.2.
i've been making board with configurationPid function of liferay, but it's not working what i think.
here's the thing
I set up three types of board to use preferences function of liferay.
From divCd information of preferences releated with board portlet keys, i can search boards specific datas.
But the problem is that when i shut down the server, datas diappear only for notice board! (divCd - 1 : NOTICE , divCd - 2 : FAQ, divCd -3 : QNA)
This phenomenon only happend to board table. 
I didn't notice there's problem in my code because in dev server (local server) i've never seen this before.
This only happen in published server. When published server's down, datas of notice board disappear! (not happend to other table yet. :) ) Blow away for real!
I guess anyone in my company have never seen this (disappearing problem!).
So, because i used configurgationPid function to make reusable board
(Notice board, FAQ board, QNA board), configurationPid is quite suspicious for me. But I couldn't find this trouble shooting cases.
I'm gonna show you all my codes that used for this!
If you know any reasons why board data deleted, Please somebody help me. 
Minor helps can alse be helpful for me! 
flow
register board types
image => enter image description here
Board types can be defined here! and JSP file show theses
configuration.jsp
<%# page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%# page import="com.liferay.portal.kernel.util.Constants"%>
<%# page import="com.osp.board.constants.OSPBoardWebPortletKeys" %>
<%# page import="com.osp.board.constants.OSPBoardWebActionKeys" %>
<%# page import="java.util.Map"%>
<%# include file="../../init.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Board Configuration</title>
</head>
<body>
<liferay-portlet:actionURL portletConfiguration="<%= true %>" var="boardDivActionURL">
<liferay-portlet:param name="target" value="boardDiv"/>
</liferay-portlet:actionURL>
<liferay-portlet:actionURL portletConfiguration="<%= true %>" var="boardActionURL">
<liferay-portlet:param name="target" value="board"/>
</liferay-portlet:actionURL>
<liferay-portlet:actionURL portletConfiguration="<%= true %>" var="boardRemoveURL">
<liferay-portlet:param name="target" value="boardRemove"/>
<liferay-portlet:param name="targetedDivCd" value=""/>
</liferay-portlet:actionURL>
<%
long divCd = Long.parseLong(portletPreferences.getValue("divCd", "0"));
String originalBoardPlid = portletPreferences.getValue("originalBoardPlid", "");
boolean mainListYn = Boolean.parseBoolean(portletPreferences.getValue("mainListYn",""));
String originalBoardPortletName = portletPreferences.getValue("originalBoardPortletName", "");
%>
<c:set var="divCd" value="<%= divCd %>"/>
<c:set var="originalBoardPlid" value="<%= originalBoardPlid %>"/>
<c:set var="mainListYn" value="<%= mainListYn %>"/>
<c:set var="originalBoardPortletName" value="<%= originalBoardPortletName %>"/>
<div class="sheet sheet-lg panel-group panel-group-flush my-5">
<div class="panel">
<form action="${boardActionURL}" method="POST">
<aui:input name="<%= Constants.CMD %>" type="hidden" value="<%= Constants.UPDATE %>" />
<div class="panel-heading">
<a class="collapse-icon sheet-subtitle" data-toggle="collapse" href="#portletInfoContentBody" aria-expanded="false" aria-controls="portletInfoContentBody">
Portlet Information
<span class="collapse-icon-closed">
<svg class="lexicon-icon lexicon-icon-angle-right" focusable="false" role="presentation" viewBox="0 0 512 512">
<path class="lexicon-icon-outline" d="M396.394 255.607c-0.22-6.936-2.973-13.81-8.272-19.111l-227.221-227.221c-11.026-11.059-28.94-11.059-39.999 0-11.058 11.026-11.058 28.941 0 39.999l206.333 206.333c0 0-206.333 206.333-206.333 206.333-11.058 11.058-11.058 28.973 0 39.999 11.059 11.059 28.972 11.059 39.999 0l227.221-227.221c5.3-5.3 8.053-12.175 8.272-19.111z"></path>
</svg>
</span>
<span class="collapse-icon-open">
<svg class="lexicon-icon lexicon-icon-angle-down" focusable="false" role="presentation" viewBox="0 0 512 512">
<path class="lexicon-icon-outline" d="M256 384c6.936-0.22 13.81-2.973 19.111-8.272l227.221-227.221c11.058-11.026 11.058-28.941 0-39.999-11.026-11.058-28.94-11.058-39.999 0l-206.333 206.333c0 0-206.333-206.333-206.333-206.333-11.059-11.058-28.973-11.058-39.999 0-11.059 11.058-11.059 28.972 0 39.999l227.221 227.221c5.3 5.3 12.174 8.053 19.111 8.272z">
</path>
</svg>
</span>
</a>
</div>
<div id="portletInfoContentBody" class="panel-body collapse show">
<div class="alert alert-info">
PortletKey : ${portletKey}
<br/>
Plid : ${plid}
</div>
<c:choose>
<c:when test="${empty boardDivs}">
<aui:select name="divSort" label="board-config-property-name-divsort" helpMessage="board-config-property-explain-divsort" disabled="true">
</aui:select>
</c:when>
<c:otherwise>
<aui:select name="preferences--divCd--" label="board-config-property-name-divsort" helpMessage="board-config-property-explain-divsort">
<option value="0"> </option>
<c:forEach items="${boardDivs}" var="boardDiv">
<c:if test="${boardDiv.divCd eq divCd}">
<option value="${boardDiv.divCd}" selected="selected">${boardDiv.divName}</option>
</c:if>
<c:if test="${boardDiv.divCd ne divCd}">
<option value="${boardDiv.divCd}">${boardDiv.divName}</option>
</c:if>
</c:forEach>
</aui:select>
</c:otherwise>
</c:choose>
<div class="form-group">
<label>
<input type="hidden" name="<portlet:namespace/>preferences--mainListYn--" id="<portlet:namespace/>preferences--mainListYn--" value="${mainListYn}"/>
<input class="toggle-switch" type="checkbox" id="mainListYn" ${mainListYn ? 'checked="true"' : ''}>
<span class="toggle-switch-label">
<liferay-ui:message key="board-config-property-name-mainlistyn"/>
<liferay-ui:icon-help message="board-config-property-explain-mainlistyn"/>
</span>
<span aria-hidden="true" class="toggle-switch-bar">
<span class="toggle-switch-handle" data-label-off="no" data-label-on="yes">
</span>
</span>
</label>
</div>
<aui:input name="preferences--originalBoardPortletName--" label="board-config-property-name-originalboard-portletname" helpMessage="board-config-property-explain-portletname" value="${originalBoardPortletName}">
</aui:input>
<aui:input name="preferences--originalBoardPlid--" label="board-config-property-name-originalboard-plid" helpMessage="board-config-property-explain-plid" value="${originalBoardPlid}">
</aui:input>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary"><liferay-ui:message key="save"/></button>
</div>
</div>
</form>
</div>
</div>
<div class="sheet sheet-lg panel-group panel-group-flush my-5">
<div class="panel">
<form action="${boardDivActionURL}" method="POST" id="boardTypeList">
<div class="panel-heading">
<a class="collapse-icon sheet-subtitle" data-toggle="collapse" href="#boardDivContentBody" aria-expanded="false" aria-controls="boardDivContentBody">
<liferay-ui:message key="board-config-property-boarddiv-title"/>
<span class="collapse-icon-closed">
<svg class="lexicon-icon lexicon-icon-angle-right" focusable="false" role="presentation" viewBox="0 0 512 512">
<path class="lexicon-icon-outline" d="M396.394 255.607c-0.22-6.936-2.973-13.81-8.272-19.111l-227.221-227.221c-11.026-11.059-28.94-11.059-39.999 0-11.058 11.026-11.058 28.941 0 39.999l206.333 206.333c0 0-206.333 206.333-206.333 206.333-11.058 11.058-11.058 28.973 0 39.999 11.059 11.059 28.972 11.059 39.999 0l227.221-227.221c5.3-5.3 8.053-12.175 8.272-19.111z"></path>
</svg>
</span>
<span class="collapse-icon-open">
<svg class="lexicon-icon lexicon-icon-angle-down" focusable="false" role="presentation" viewBox="0 0 512 512">
<path class="lexicon-icon-outline" d="M256 384c6.936-0.22 13.81-2.973 19.111-8.272l227.221-227.221c11.058-11.026 11.058-28.941 0-39.999-11.026-11.058-28.94-11.058-39.999 0l-206.333 206.333c0 0-206.333-206.333-206.333-206.333-11.059-11.058-28.973-11.058-39.999 0-11.059 11.058-11.059 28.972 0 39.999l227.221 227.221c5.3 5.3 12.174 8.053 19.111 8.272z">
</path>
</svg>
</span>
</a>
</div>
<div id="boardDivContentBody" class="panel-body collapse show">
<div class="form-group">
<div class="table-responsive-md">
<table class="table table-bordered">
<!-- <colgroup>
<col width="5%">
<col width="16.5%">
<col width="25.5%">
<col width="10%">
<col width="23%">
<col width="6%">
<col width="8%">
</colgroup> -->
<thead>
<tr>
<th scope="col" class="text-center"><liferay-ui:message key="table-index"/></th>
<c:forEach items="${locales}" var="locale">
<th scope="col" class="text-center">Title(${locale})</th>
</c:forEach>
<th scope="col" class="text-center"><liferay-ui:message key="board-config-property-boarddiv-column-content"/></th>
<th scope="col" class="text-center"><liferay-ui:message key="board-config-property-boarddiv-column-name"/></th>
<th scope="col" class="text-center"><liferay-ui:message key="board-config-property-boarddiv-column-fileuse"/></th>
<th scope="col" class="text-center"><liferay-ui:message key="board-config-property-boarddiv-column-popupuse"/></th>
<th scope="col" class="text-center"><liferay-ui:message key="board-config-property-boarddiv-column-replyuse"/></th>
<th scope="col" class="text-center"></th>
</tr>
</thead>
<tbody data-entity="boardDiv">
<c:choose>
<c:when test="${empty boardDivs}">
<tr data-nodata="true">
<td class="text-center text-danger" colspan="8">
<liferay-ui:message key="board-config-property-boarddiv-result-noboarddiv"/>
</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${boardDivs}" var="boardDiv" varStatus="vs">
<tr>
<input type="hidden" name="<portlet:namespace/>idx" value="${vs.count}"/>
<input type="hidden" name="<portlet:namespace/>divCd" value="${boardDiv.divCd}"/>
<td scope="col" class="text-center">${vs.count}</td>
<c:forEach items="${locales}" var="locale">
<c:set var="titleKey" value="title_${locale}"/>
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>title_${locale}_${vs.count}" value="${boardDiv[titleKey]}" maxlength="30"/>
</td>
</c:forEach>
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>content_${vs.count}" value="${boardDiv.content}" maxlength="30"/>
</td>
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>divName_${vs.count}" value="${boardDiv.divName}" maxlength="30"/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>fileUploadUseYn_${vs.count}" ${boardDiv.fileUploadUseYn ? 'checked="true"' : ''}/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>popupYn_${vs.count}" ${boardDiv.popupYn ? 'checked="true"' : ''}/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>replyYn_${vs.count}" ${boardDiv.replyYn ? 'checked="true"' : ''}/>
</td>
<td scope="col" class="text-center">
<button class="btn btn-default" type="button" data-target-entity="remove" data-event="remove" data-div-cd="${boardDiv.divCd}">
<i class="icon-trash"></i>
</button>
</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
</table>
</div>
</div>
<div class="d-flex d-flex justify-content-between">
<button type="button" class="btn btn-outline-dark" data-target-entity="boardDiv">
<i class="icon-plus"></i>
Board Type
</button>
<button type="submit" class="btn btn-primary"><liferay-ui:message key="save"/></button>
</div>
</div>
</form>
</div>
</div>
</body>
</html>
<script type="text/javascript">
$(function(){
$('#mainListYn').on('change', function(){
$('#<portlet:namespace/>preferences--mainListYn--').val($(this).prop('checked'));
});
$(document).on('click','[data-target-entity]', function(){
var target = $('[data-entity="'+$(this).data('targetEntity')+'"]');
if($(target).find('[data-nodata="true"]').length > 0){
$(target).empty();
}
var targetType = $(this).data("targetEntity") || "";
if(targetType == "remove"){
var targetedDivCd = $(this).data('divCd') || '';
if(targetedDivCd != ""){
$.ospConfirm({
modalDialogClass : 'modal-md',
title : '<liferay-ui:message key="board-app-delete-modal-title"/>',
confirmText : '<liferay-ui:message key="board-app-notice-delete-modal-btn"/>',
body : '<liferay-ui:message key="board-app-delete-modal-body"/>',
closeText : '<liferay-ui:message key="board-app-delete-cancel"/>',
onSubmit : function(result){
if(result){
var actionURL = "${boardRemoveURL}";
actionURL +="&_com_liferay_portlet_configuration_web_portlet_PortletConfigurationPortlet_targetedDivCd=" + targetedDivCd;
window.location = actionURL.toString();
}
}
});
}else{
$(this).closest("tr").remove();
}
return;
}
var idx = $(target).find('tr').length + 1;
if('content' in document.createElement('template')){
var tmpl = document.querySelector('#boardDivTmpl');
var clone = document.importNode(tmpl.content, true);
$(clone).find("tr").prepend(
$('<input/>').attr({
type : 'hidden',
name : '<portlet:namespace/>idx',
value : idx
}),
$('<input/>').attr({
type : 'hidden',
name : '<portlet:namespace/>divCd',
value : 0
})
);
var tds = clone.querySelectorAll("td");
tds.forEach( (td, i) => {
if(i == 0){
$(td).text(idx);
}else{
if($(tds).eq(i).find('input').length > 0){
var input = $(td).find('input:eq(0)');
var bName = $(input).attr('name');
var aName = bName.replace('_idx', '_'+idx);
$(tds).eq(i).find('input:eq(0)').attr('name', aName);
}
}
});
$(target).append(clone);
} else{
var input = $('<input/>').addClass('form-control'),
checkbox = $('<input/>').attr('type', 'checkbox'),
appendTd = $('<td/>').addClass('text-center');
$('<tr/>').append(
$('<input/>').attr({
type : 'hidden',
name : '<portlet:namespace/>idx',
value : idx
}),
$(appendTd).clone()
.text(idx),
$(appendTd).clone()
.append(
$(input).clone().attr('name', '<portlet:namespace/>title_ko_KR_'+idx)
),
$(appendTd).clone()
.append(
$(input).clone().attr('name', '<portlet:namespace/>title_en_US_'+idx)
),
$(appendTd).clone()
.append(
$(input).clone().attr('name', '<portlet:namespace/>content_'+idx)
),
$(appendTd).clone()
.append(
$(input).clone().attr('name', '<portlet:namespace/>divName_'+idx)
),
$(appendTd).clone()
.append(
$(checkbox).clone().attr('name', '<portlet:namespace/>fileUploadUseYn_'+idx)
),
$(appendTd).clone()
.append(
$(checkbox).clone().attr('name', '<portlet:namespace/>popupYn_'+idx)
),
$(appendTd).clone()
.append(
$(checkbox).clone().attr('name', '<portlet:namespace/>replyYn_'+idx)
)
).appendTo(target);
}
});
});
</script>
<template id="boardDivTmpl">
<tr>
<td scope="col" class="text-center"></td>
<c:forEach items="${locales}" var="locale">
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>title_${locale}_idx"/>
</td>
</c:forEach>
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>content_idx"/>
</td>
<td scope="col" class="text-center">
<input type="text" class="form-control" name="<portlet:namespace/>divName_idx"/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>fileUploadUseYn_idx"/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>popupYn_idx"/>
</td>
<td scope="col" class="text-center">
<input type="checkbox" name="<portlet:namespace/>replyYn_idx"/>
</td>
<td>
<button class="btn btn-default" type="button" data-target-entity="remove">
<i class="icon-trash"></i>
</button>
</td>
</tr>
</template>
If you save for delete, you can see if they exists on my table!
image => enter image description here
but, It was not simple if i need to use OSP_BoardDiv.
In main page, I must know exact plid to get to the right board type.
For this, I should set plid, divCd before you main page for preview of
notice board. And i set it on html tags.
image => enter image description here
If board types are set, i can read information from BoardRender.
And the next thing is all the same. Controlling data with action,
render, resources ... but i can't find any problem on my codes!
I must get plId infos to nevigate user to get to the right board. So, I access to xml datas of the PortletPreferences table. If portletId is same with board portlet and divCd is same, get datas!
BoardRender.java
package com.osp.board.web.board.command;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.PortletPreferences;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCRenderCommand;
import com.liferay.portal.kernel.service.PortletPreferencesLocalServiceUtil;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.osp.board.constants.ConstantsPagePath;
import com.osp.board.constants.OSPBoardWebPortletKeys;
import com.osp.board.model.Board;
import com.osp.board.model.BoardDiv;
import com.osp.board.service.BoardDivLocalServiceUtil;
import com.osp.board.service.BoardLocalServiceUtil;
import com.osp.constants.CustomRoleConstants;
import com.osp.constants.MessageConstants;
import com.osp.constants.SiteNameConstants;
import com.osp.search.constants.OSPSearchPortletKeys;
import com.osp.util.CustomUtil;
import com.osp.util.OSPPropertiesUtil;
import com.osp.util.OSPUsersUtil;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.osgi.service.component.annotations.Component;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
#Component(
immediate = true,
property = {
"javax.portlet.name=" + OSPBoardWebPortletKeys.BOARD_PORTLET_KEY,
"mvc.command.name=/",
"javax.portlet.version=3.0"
},
service = MVCRenderCommand.class
)
public class BoardRender implements MVCRenderCommand {
private static final Log _log = LogFactoryUtil.getLog(BoardRender.class);
#Override
public String render(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException {
ThemeDisplay themeDisplay = (ThemeDisplay) renderRequest.getAttribute(WebKeys.THEME_DISPLAY);
String isMainPage = renderRequest.getPreferences().getValue("mainListYn", "false");
String jspPage = ConstantsPagePath.OSP_BOARD_LIST;
String escapeTag = "<(/)?([a-zA-Z]*)(\\\\s[a-zA-Z]*=[^>]*)?(\\\\s)*(/)?>";
long divCd = Long.parseLong(renderRequest.getPreferences().getValue("divCd", "0"));
try {
if(divCd > 0) {
BoardDiv boardDiv = BoardDivLocalServiceUtil.getBoardDiv(divCd);
Map<String, Object> boardDivMap = new HashMap<String, Object>();
boardDivMap.put("title", boardDiv.getTitle(themeDisplay.getLanguageId()));
// permission check start.
String divName = GetterUtil.getString(boardDiv.getDivName(), "FAQ").toUpperCase();
boolean permission = false;
if(isMainPage.equals("true")) {// write only portal, site admins.
List<PortletPreferences> searchPreferences = null;
String searchNamespace = "";
String siteName = CustomUtil.strNull(OSPPropertiesUtil.getPortalSiteName(),"1");
renderRequest.setAttribute("siteName", siteName);
if(siteName.equals(SiteNameConstants.BIO)) {
searchPreferences = PortletPreferencesLocalServiceUtil.getPortletPreferences().stream().filter(pp -> pp.getPortletId().equals(OSPSearchPortletKeys.TOTAL_LIST_SEARCH_PORTLET_KEY)).collect(Collectors.toList());
searchNamespace = PortalUtil.getPortletNamespace(OSPSearchPortletKeys.TOTAL_LIST_SEARCH_PORTLET_KEY);
}else {
searchPreferences = PortletPreferencesLocalServiceUtil.getPortletPreferences().stream().filter(pp -> pp.getPortletId().equals(OSPSearchPortletKeys.MATERIAL_LIST_SEARCH_PORTLET_KEY)).collect(Collectors.toList());
searchNamespace = PortalUtil.getPortletNamespace(OSPSearchPortletKeys.MATERIAL_LIST_SEARCH_PORTLET_KEY);
}
if(searchPreferences != null) {
long searchPlid = searchPreferences.get(0).getPlid();
renderRequest.setAttribute("searchPlid", searchPlid);
renderRequest.setAttribute("searchNamespace", searchNamespace);
}
List<PortletPreferences> boardPrefereneces = PortletPreferencesLocalServiceUtil.getPortletPreferences().stream().filter(pp -> pp.getPortletId().equals(OSPBoardWebPortletKeys.BOARD_PORTLET_KEY)).collect(Collectors.toList());
Map<String, Map<String, Object>> resultMap = new HashMap<String, Map<String,Object>>();
List<BoardDiv> boardTypeList = BoardDivLocalServiceUtil.getBoardDivListWithBoardName();
for(PortletPreferences pp : boardPrefereneces) {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
InputSource is = new InputSource();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
is.setCharacterStream(new StringReader(pp.getPreferences()));
Document document = docBuilder.parse(is);
document.getDocumentElement().normalize();
if(document.getElementsByTagName("value").getLength() > 0 ) {
NodeList valueList = document.getElementsByTagName("value");
String nodeValue = "";
for(BoardDiv bdiv : boardTypeList) {
for(int i = 0; valueList.getLength() > i; i++) {
Node valueNode = valueList.item(i);
nodeValue = valueNode.getTextContent();
if(String.valueOf(bdiv.getDivCd()).equals(nodeValue)) {
Map <String, Object> dataMap = new HashMap<>();
dataMap.put("plid",pp.getPlid());
dataMap.put("portletId",pp.getPortletId());
dataMap.put("divCd", nodeValue);
resultMap.put(bdiv.getContent().toUpperCase(), dataMap);
break;
}
}
}
}
}
List<Board> boardListForMainNotice = new ArrayList<Board>();
List<Board> boardListForMainFaq = new ArrayList<Board>();
for(BoardDiv bdiv : boardTypeList) {
if("NOTICE".equals(bdiv.getContent().toUpperCase())) // notice
boardListForMainNotice = BoardLocalServiceUtil.getBoardListByDivcdSiteGroupIdsForMain(bdiv.getDivCd(), themeDisplay.getScopeGroupId(), 0, 3, themeDisplay.getLanguageId());
if("FAQ".equals(bdiv.getContent().toUpperCase())) // faq
boardListForMainFaq = BoardLocalServiceUtil.getBoardListByDivcdSiteGroupIdsForMain(bdiv.getDivCd(), themeDisplay.getScopeGroupId(), 0, 4, themeDisplay.getLanguageId());
}
for(Board board : boardListForMainNotice) {
board.setTitle(board.getTitle(LocaleUtil.KOREA));
board.setCreateDate(board.getCreateDate());
board.setContent(board.getContent(LocaleUtil.KOREA).replaceAll(escapeTag, ""));
}
for(Board board : boardListForMainFaq){
board.setTitle(board.getTitle(LocaleUtil.KOREA));
board.setCreateDate(board.getCreateDate());
board.setContent(board.getContent(LocaleUtil.KOREA).replaceAll(escapeTag, "").replaceAll(" ", "<br>").replaceAll("<br>", ""));
}
renderRequest.setAttribute("boardInfos", resultMap);
renderRequest.setAttribute("boardListForMainNotice", boardListForMainNotice);
renderRequest.setAttribute("boardListForMainFaq", boardListForMainFaq);
jspPage = ConstantsPagePath.OSP_MAIN_BOARD_LIST;
}else if("QNA".equals(divName)) {// admins or writer.
permission = themeDisplay.getPermissionChecker().isSignedIn();
}else if("FAQ".equals(divName)||divName.equals("NOTICE")) {
permission = OSPUsersUtil.isRegularRole(themeDisplay.getUser(), CustomRoleConstants.ADMINISTRATOR);
if(!permission) permission = OSPUsersUtil.isSiteRole(themeDisplay.getUser(), themeDisplay.getScopeGroupId(), CustomRoleConstants.SITE_ADMINISTRATOR);
}else {
_log.debug("##### DivName '"+divName+"' is not supported yet.");
_log.debug("##### Check role like FAQ(Write only admins.).");
permission = OSPUsersUtil.isRegularRole(themeDisplay.getUser(), CustomRoleConstants.ADMINISTRATOR);
if(!permission) permission = OSPUsersUtil.isSiteRole(themeDisplay.getUser(), themeDisplay.getScopeGroupId(), CustomRoleConstants.SITE_ADMINISTRATOR);
}
renderRequest.setAttribute("permission", permission);
// permission check end.
renderRequest.setAttribute("boardDiv", boardDivMap);
}else {
SessionErrors.add(renderRequest, MessageConstants.SEARCH_ERROR);
}
} catch (Exception e) {
_log.error(e);
jspPage = ConstantsPagePath.OSP_MAIN_BOARD_LIST;
renderRequest.setAttribute("permission", false);
SessionErrors.add(renderRequest, MessageConstants.SEARCH_ERROR);
}
// session message print.
String msgType = ParamUtil.getString(renderRequest, "msgType", "");
if(msgType.equals("error")) {
SessionErrors.add(renderRequest, ParamUtil.getString(renderRequest, "ssMsg", ""));
}else if(!msgType.equals("")) {
SessionMessages.add(renderRequest, ParamUtil.getString(renderRequest, "ssMsg", ""));
}
SessionMessages.add(renderRequest, PortalUtil.getPortletId(renderRequest) + SessionMessages.KEY_SUFFIX_HIDE_DEFAULT_ERROR_MESSAGE);
return jspPage;
}
public static void main(String[] args) {
}
}
BoardConfig.java
package com.osp.board.web.board.config;
import com.liferay.portal.configuration.metatype.annotations.ExtendedObjectClassDefinition;
import com.osp.board.constants.OSPBoardWebPortletKeys;
import aQute.bnd.annotation.metatype.Meta;
#ExtendedObjectClassDefinition(
category = "board",
scope = ExtendedObjectClassDefinition.Scope.SYSTEM
)
#Meta.OCD(
id = OSPBoardWebPortletKeys.BOARD_CONFIG_PORTLET_KEY
)
public interface BoardConfig {
}

Update form from another form using <f: ajax> in JSF

Good day,
I am developing an application in java server faces 2.2.20 and mariadb 10.4 databases.
I have a problem when updating with f: ajax to another form where I have a table that lists the products with their respective images entered, but the images returned by the method from the bean to the img in html are not displayed, although the image if it has in the src its respective route; The good content as text if it is updated correctly without reloading the page this means that if ajax works in part.
This is the code where the product data is entered and the image is uploaded to the controller.
<h:form id="crearCatalogos" enctype="multipart/form-data"> <!--prependId="false" -->
<div class="container">
<div class="row">
<div class="col-lg-5">
<fieldset>
<legend> Informacion:</legend>
<h:messages style="color:red"></h:messages>
<label>Nombre de categoria: </label><br/>
<h:inputText value="#{FileUploadFormBeanRequest.nombreCatalogo}" id="primerNombre" class="inputPersonalizado" html5:placeholder="Ingrese el nombre" maxlength="20" required="true" validatorMessage="No debe superar 20 caracteres" requiredMessage="Ingrese el nombre"></h:inputText><br/><br/>
<label>Seleccionar imagen: </label><br/>
<h:inputFile id="imgInp" value="#{FileUploadFormBeanRequest.archivoCarga}" validator="#{FileUploadFormBeanRequest.validarImagenCategoria}" class="inputPersonalizadoFile"> </h:inputFile>
<br/><br/>
<h:commandButton class="btn btn-primary" value="Cargar">
<f:ajax render="#form : formVerCatalogos : table_verCatalogos" event="action" execute="#form" listener="#{FileUploadFormBeanRequest.guardarDatosCategoria()}"></f:ajax>
</h:commandButton>
</fieldset>
<br/><br/>
</div>
<div class="col-lg-5 imgCategorias">
<div class="text-center">
<img id="noImagen54" src="../TEMPLATE/img/noImagen.jpeg" class="rounded img-thumbnail" alt="..."/>
<img id="imagenCategoriaFile" src="#" class="rounded img-thumbnail imagenCategoriaFile" alt="..."/>
</div>
</div>
</div>
</div> ​
</h:form>
first form view
second view with data
This is the code of the controller method that is called from the commandButton of the view, which is responsible for saving the data entered of the product and the respective image.
public void guardarDatosCategoria() {
this.archivoCarga = archivoCarga;
try (InputStream input = archivoCarga.getInputStream()) {
String fileName = archivoCarga.getSubmittedFileName();
Calendar hoy = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("yyyyMMdd-hhmmss");
String[] ext = fileName.split("\\.");
fileName = ext[0] + formatter.format(hoy.getTime()) + "." + ext[1];
File directorio = new File(folder+"/"+this.nombreCatalogo);
if(!directorio.exists()){
if(directorio.mkdir()){
directorio.mkdir();
Files.copy(input, new File(directorio, fileName).toPath());
//System.out.println(directorio.getAbsolutePath());
}else{
System.out.println("Error al crear directorio");
}
}
//String salida = FacesContext.getCurrentInstance().getExternalContext().getApplicationContextPath();
//System.out.println(salida);
Catalogo objCatalogo = new Catalogo();
objCatalogo.setNombre(this.nombreCatalogo);
catalogoFacadeLocal.create(objCatalogo);
Imagen objImagen = new Imagen();
objImagen.setRuta("../Resources/img/Categorias/"+this.nombreCatalogo+"/"+fileName);
objImagen.setEstado("Principal");
objImagen.setIdCatalogo(objCatalogo);
imagenFacadeLocal.create(objImagen);
} catch (Exception e) {
e.printStackTrace();
}
this.archivoCarga=null;
this.nombreCatalogo="";
}
This is the view code that I need to reload using f: ajax de jsf
<!--VER CATEGORIAS -->
<div class="tab-pane fade active show" id="pills-home" role="tabpanel" aria-labelledby="pills-home-tab">
<h:form id="formVerCatalogos">
<table id="table_verCatalogos" class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">CATEGORIA</th>
<th scope="col">TIPO</th>
<th scope="col">IMAGEN</th>
</tr>
</thead>
<tbody>
<c:forEach items="#{FileUploadFormBeanRequest.listarImagenes()}" var="catalogoImg" varStatus="paso" rendered="#{!empty FileUploadFormBeanRequest.listarImagenes()}" >
<tr>
<th scope="row">#{paso.index+1}</th>
<td>#{catalogoImg.idCatalogo.nombre}</td>
<td>#{catalogoImg.estado}</td>
<td><h:graphicImage id="noImagen" value="#{catalogoImg.ruta}" class="rounded img-thumbnail img_ver_categorias"></h:graphicImage> </td>
</tr>
</c:forEach>
</tbody>
</table>
</h:form>
</div>
[enter image description here][3]
This is the code of the controller that is responsible for returning the data entered, to be displayed in the table that I need to reload.
public List<Imagen> listarImagenes(){
try {
return imagenFacadeLocal.findAll();
} catch (Exception e) {
return null;
}
}
This is how you look when the data entered is saved and the jsf ajax is executed, but the image cannot be visualized even if I look at the src of the img tag, the path is found. The only way to view the page is to reload the entire page arbitrarily, but it is not the idea.
in this view the text rendering is done, but the image is not displayed
Inspecting the element with f12, we can see that the img tag, if it has the correct path, but is not displayed with the JSF f: ajax.
I am very grateful that you give me a help, I have already searched, read, documented and the truth is that I cannot solve it on my own, I do not understand what it takes. Happy day thank you very much.
INSPECTING THE VIEW WITH F12, it is shown that the src attribute has the image path

Loading a Partial view which has a complex model of many sub models into a jquery ui tab

I get an error when loading a particular view via an Html.action call to an action and Controller, into a jquery Tab.
The other View is loaded successfully via an HTML.Partial call.
How do I get this other particular partial loaded please.
The tab where the error happens is tab4.
The commented out HTML.Partial call works to a point but when it loads that Partial (User), which has multiple models in it's containing model,..those other models are null and it's iteration over them crashes.
(That partial is beneath the first block of code.)
If I try load it from an action Call, then
the JQuery function ("$#tabs").tabs crashes with ".tabs" is undefined
TIA
Code:
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Tabs - Content via Ajax</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function ()
{
$("#tabs").tabs({
beforeLoad: function (event, ui)
{
ui.jqXHR.fail(function ()
{
ui.panel.html(
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
"If this wouldn't be a demo.");
});
}
});
});
</script>
<div id="tabs">
<ul>
<li>Person Detail</li>
<li>Addresses</li>
<li>Role Detail</li>
<li>User Detail</li>
</ul>
<div id="tabs-1">
#*#Html.Partial("~/Views/Person/Index.cshtml")*#
</div>
<div id="tabs-2">
#*#Html.Partial("~/Views/Address/Index.cshtml")*#
</div>
<div id="tabs-3">
#Html.Partial("~/Views/IdentityRole/List.cshtml", new List<Catalyst.Shared.IdentityRole>())
</div>
<div id="tabs-4">
#Html.Action("List", "User");
#*#Html.Partial("~/Views/User/List.cshtml", new Catalyst.Mvc.IdentityUserPersonViewModel())*#
</div>
</div>
The Partial which I want to load, but needs data, which I think would work if I called the Action as opposed to calling the Partial.
#model Catalyst.Mvc.IdentityUserPersonViewModel
#{
ViewBag.User = "List";
}
<div class="panel panel-default" style="width:1400px !important;text-align:center ">
<div class="panel-heading">
<h3>Users</h3>
</div>
<div class="panel-body">
<div style="text-align:right;">#Html.ActionLink("Add", "Create", null, new { #class = "btn btn-default" })</div>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>
UserName
</th>
<th>
Password
</th>
<th>
Title
#*#Html.DisplayNameFor(model => model.)*#
</th>
<th>
FirstName
#*#Html.DisplayNameFor(model => model.)*#
</th>
<th>
LastName
</th>
<th>
PhoneNumber
</th>
<th>
Email
</th>
<th>
Company and Branch
</th>
<th></th>
<th></th>
</tr>
</thead>
#for (var i = 0; i < Model.identityUsers.Count(); i++)
{
<tr>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.identityUsers[i].UserName)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.EditorFor(x => Model.identityUsers[i].PasswordHash, new { htmlAttributes = new { #class = "form-control", placeholder = "Password", Type = "password" } })
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Title)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Name)
</a>
</td>
<td>
<a href="#Url.Action("Edit", "User" , new {id=Model.UserPersons[i].UserPersonId})">
#Html.DisplayFor(x => Model.UserPersons[i].Surname)
</a>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=Model.identityUsers[i].Id})">
#Html.DisplayFor(x => Model.identityUsers[i].Email)
</a>*#
</td>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=Model.identityUsers[i].Id})">
#Html.DisplayFor(x => Model.identityUsers[i].PhoneNumber)
</a>*#
</td>
<td>
#*<a href="#Url.Action("Edit", "User" , new {id=item.ID})">
#Html.DisplayFor(x => item.PhoneNumber)
</a>*#
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id =
Model.identityUsers[i].Id })
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { id =
Model.identityUsers[i].Id })
</td>
</tr>
}
</table>
</div>
The Controller of the view I can't get laoded
public class UserController : Controller
{
private IdentityUserBo identityUserBo;
private PersonBo personBo;
private IdentityUserPersonBo identityuser_personBo;
IdentityUserPersonViewModel model = new IdentityUserPersonViewModel();
public UserController(IdentityUserBo boIdentityUser, PersonBo boPerson, IdentityUserPersonBo boIdentityUserPerson )
{
this.identityUserBo = boIdentityUser ?? throw new ArgumentNullException("boIdentityUser");
this.personBo = boPerson ?? throw new ArgumentNullException("boPerson");
this.identityuser_personBo = boIdentityUserPerson ?? throw new ArgumentNullException("boIdentityUserPerson");
}
public ActionResult Index()
{
return RedirectToAction("List");
}
public ActionResult List()
{
ExBool result = null;
IdentityUserPersonViewModel userPersonViewModel = new IdentityUserPersonViewModel();
result = this.identityUserBo.List(out List<IdentityUser> identityUsers);
if (!result.Success) throw new Exception(result.Messages);
if (identityUsers == null) throw new Exception("Could not load IdentityUsers");
// Ideally see detail eg branch and tel and email from their respective tables
userPersonViewModel.identityUsers = identityUsers;
//Get the Persons, match these via Person.Id -> IdentityUserPerson.FKPersonId + IdentityUserPerson.FKUserId -> IdentityUser.ID
List<Person> persons = null;
result = this.personBo.List(out persons);
//IdentityUserPersonViewModel viewModel = new IdentityUserPersonViewModel();
userPersonViewModel.persons = persons;
// Get the IdentityUserPersons
List<IdentityUserPerson> identityUserPersons = null;
result = this.identityuser_personBo.List(out identityUserPersons);
IdentityUserPerson UPRec = new IdentityUserPerson();
Person PRec = new Person();
userPersonViewModel.UserPersons = new List<UserPerson>();
foreach (IdentityUser rec in userPersonViewModel.identityUsers)
{
UPRec = identityUserPersons.Find(x => x.FKUserID == rec.Id);
if (UPRec != null)
{
//UserId, UserPersonId, + Person.Id + Person.Name + Person.Surname
PRec = persons.Find(y => y.ID == UPRec.FKPersonID);
UserPerson UsrPers = new UserPerson();
UsrPers.UserId = rec.Id;
UsrPers.UserPerson_FKPersonId = UPRec.FKPersonID;
UsrPers.UserPerson_FKUserId = UPRec.FKUserID;
UsrPers.Name = PRec.FirstName;
UsrPers.Surname = PRec.LastName;
UsrPers.Title = PRec.TitleCode;
userPersonViewModel.UserPersons.Add(UsrPers);
}
else
{
UserPerson UsrPers = new UserPerson();
userPersonViewModel.UserPersons.Add(UsrPers);
}
}
return View(userPersonViewModel);
}
Check your console what error you got.
and also change this in tab4
#{
#Html.Partial("List", new Catalyst.Mvc.IdentityUserPersonViewModel())
}

Login required twice after logging out due to ViewExpiredException

I have a JSF page on Websphere Process Server (on top of WAS 7) which has ViewExpiredException. When this happens I want the user to be logged out and then logged back in
I've set up a redirect on this exception in web.xml to the following logout page:
<%
session.invalidate();
response.sendRedirect("ibm_security_logout?logoutExitPage=/faces/ToDosOpen.jsp");
%>
Which then redirects to a login page:
<%# page import="com.ibm.wbit.tel.client.jsf.infrastructure.Messages, java.util.Locale" language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%
String contextPath = request.getContextPath();
Locale locale = request.getLocale();
final String SECURITY_CHECK = "j_security_check";
%>
...
</head>
<body>
...
<h1><%= Messages.getString("LOGIN_LINE", locale) %></h1>
<div class="help-text"><%= Messages.getString("LOGIN_LINE_DESCR", locale) %></div>
<form target="_top" method="POST" action=<%= SECURITY_CHECK %>>
<table id="login-form">
<tr>
<td><%= Messages.getString("LOGIN_NAME", locale) %>:</td>
<td><input type="text" name="j_username"></td>
</tr>
<tr>
<td><%= Messages.getString("LOGIN_PASSWORD", locale) %>:</td>
<td><input type="password" name="j_password"></td>
</tr>
<tr>
<td id="login-button" colspan="2">
<input type="submit" name="login" value="
<%= Messages.getString("BUTTON_LOGIN", locale) %>"></td>
</tr>
</table>
</form>
And when you login you're redirected to the page that caused the exception in the first place. Except what actually happens is the exception is thrown again, and back we go to the login page.
So you have to login twice.
Not sure what to do about this or where to start looking. Any help would be appreciated.
I have looked through existing questions on this and haven't been able to solve it.
EDIT: I've forgotten to mention that this works fine if the action that triggered the exception was a refresh, but fails (having to login twice) if the action was clicking on a commandbar.
Finally solved it using the following ViewHandler.
This basically recreates the view that expired. In the case where there were POST parameters, they've obviously been lost so any view that cannot be created without them needs special handling.
Hopefully this is useful to anyone else who runs into this problem, and please let me know if you see anything wrong with this solution because I am not 100% confident in it.
/**
* This class just handles cases where the session expired
* which causes an exception on reload.
*/
public class ViewExpiredHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
public ViewExpiredHandler(ViewHandler wrapped) {
this.wrapped = wrapped;
}
#Override
public UIViewRoot restoreView( FacesContext ctx, String viewId )
{
UIViewRoot viewRoot = super.restoreView( ctx, viewId );
try {
if ( viewRoot == null) {
viewRoot = super.createView( ctx, viewId );
ctx.setViewRoot( viewRoot );
}
} catch (Exception e) {
e.printStackTrace();
}
return viewRoot;
}
#Override
protected ViewHandler getWrapped() {
return wrapped;
}
}

Resources