I'm creating a servlet to display a front end of a little program I've produced, In this program I have a LinkedList call Execution Queue that I place in a string builder.
public String getJobsForPrint() {
Iterator<JobRequest> it = ExecutionQueue.iterator();
StringBuilder result = new StringBuilder();
String NEW_LINE = System.getProperty("line.separator");
while (it.hasNext()) {
JobRequest temp = it.next();
result.append(this.getClass().getName()).append(" Object {").append(NEW_LINE);
result.append(" User ID: ").append(temp.getUserID());
result.append(" Start Date: ").append(temp.getStartDate());
result.append(" End Date: ").append(temp.getEndDate());
result.append(" Deadline Date: ").append(temp.getDeadDate());
result.append(" Department: ").append(temp.getDepartment());
result.append(" Project Name: ").append(temp.getProjectName());
result.append(" Project Application: ").append(temp.getProjectApplication());
result.append(" Priority: ").append(temp.getPriority());
result.append(" Cores: ").append(temp.getCores());
result.append(" Disk Space: ").append(temp.getDiskSpace());
result.append(" Analysis: ").append(temp.getAnaylsis()).append(NEW_LINE);
result.append("}");
}
return result.toString();
on my servlet side I call the string by:
protected void processExecutionQueue(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Execution Queue</title>");
out.println("</head>");
out.println("<body>");
out.println("<div>");
out.println("<div style='position:absolute; top:20px; right: 20px;'><a href='/ProjectAndBackend/index.jsp'>LOGOUT</a></div>");
out.println("</div>");
out.println("<p>Queue:</p>");
out.println("Execution Queue:" + SystemServlet.getScheduler().getJobsForPrint());
out.println("</body>");
out.println("</html>");
}
So now I display strings after each other with all the data taken from the linkedlist. I want to on the webpage side, be able to take that data and put it into a table so that it looks neater and not just strings tossed onto the webpage.
How would I implement a html to show the specific elements of the string in certain aspects
So with example below I have the headers then where the data is take the element from the string and keep writing it out until all the data from the iterator displayed
<table border="1">
<tr>
<th>User ID</th>
<th>Start Date</th>
</tr>
<tr>
<td>User ID DATA</td>
<td>Start Date DATA</td>
</tr>
Or if anyone can direct me to an example as I can't find any with my current searches.
When you build the StringBuilder use HTML tags to place each in a row.
Code should be something like this
StringBuilder result = new StringBuilder();
result.append("<tr><td>").append(User ID DATA).append("</td><td>").append(Start Date DATA).append("</td></tr>");
Note:
1.You need to create the base html and table header columns inside processExecutionQueue() method.
2. Only the data row needs to be created in getJobsForPrint() method.
So when the result is passed from getJobsForPrint() it will be embedded into other HTML files.
Hope you can complete the code with this suggestion.
Related
Okay so I have two Java Servlets, one for letting the user select which images to delete (DeleteImages) and another for actually deleting the images (HandleDelete). DeleteImages displays all the images in the container with a checkbox HTML form for the user to select which images to delete. Then, using POST the servlet passes that information along to HandleDelete which iterates over which images it received and deletes them.
I actually had this working, but then I tried to change the structure of the code (have DeleteImages forward to a .jsp file that output the HTML form which would then forward to HandleDelete) but that didn't work out, so I'm trying to go back to the old way and now it's not working even though I'm pretty sure it's the same as I had before.
From DeleteImages:
// retrieve image files
List<? extends SwiftObject> objs = os.objectStorage().objects().list("imageFiles");
out.println("<!DOCTYPE html><html><head><title>Object Storage - Delete</title><link rel='stylesheet' href='stylesheet.css' type='text/css' /></head>"
+ "<body>
<h1>Select images to Delete from container</h1>
<form method='POST' enctype='multipart/form-data' action='/ImageUpload/OSHandleDelete'>");
for (SwiftObject o : objs) {
// omitted code that gets the image's name, date last modified, and filepath (all Strings, I know this works)
out.println("<b>Name:</b> " + name + "<br/> <b>Time of Upload:</b> " + date + "<br/>"
+ "<input type='checkbox' name='"+name+"'> "
+ "<img src='"+filepath+"' alt='' style='max-width:800px;' /> <br/> <br/> <br/> ");
}
out.println("<input type='submit' value='Delete Images' /></form>");
out.println("</form> <br/> <br/> <div><br/><a class='return' href='index.jsp'><b>Click here to return home</b></a><br/><br/></div> <br/> <br/></body></html>");
From HandleDelete:
Enumeration<String> parameterNames = request.getParameterNames();
if (!parameterNames.hasMoreElements())
System.out.println("no parameters (null)");
while (parameterNames.hasMoreElements()) {
String paramName = parameterNames.nextElement();
System.out.println("*****************");
System.out.println("parameter: " + paramName);
String[] vals = request.getParameterValues(paramName);
if (vals == null)
System.out.println(" vals is null for " + paramName);
else {
for (int i = 0; i < vals.length; i++) {
System.out.println(" vals["+i+"]: " + vals[i]);
}
}
Right now I don't have HandleDelete actually doing anything besides print statements. This is because I use request.getParameter("<name>") to find out whether the user checked image of <name> (i.e. if it's null it was not checked but if it's not null it was checked).
The HTML form displays perfectly with the images and everything. My problem is that no matter what's checked in the HTML form, HandleDelete always prints to the console no parameters (null) meaning nothing was passed from DeleteImages to HandleDelete. I have a feeling the problem comes from either (1) the setAttribute statement in DeleteImages or (2) something with the HTML form. I've done a lot of searching and I'm pretty confident what I have is right though and I really can't figure out what's causing this issue (especially since I'm pretty sure this is exactly what I had before and it worked). Does anyone have any ideas?
I found the error: I included enctype=multipart/form-data
Not exactly sure why that caused the error but I removed that part and now it's passing the parameters perfectly. Thanks for your help guys!
The row contains
row number -- name surname -- instructor name-- E
</tr>
<tr height=20 style='height:15.0pt'>
<td height=20 class=xl6429100 align=right width=28 style='height:15.0pt;
border-top:none;width:21pt'>row number</td>
<td class=xl8629100 width=19 style='border-top:none;border-left:none;
width:14pt'> </td>
<td class=xl6529100 width=137 style='border-top:none;border-left:none;
width:103pt'>name</td>
<td class=xl6529100 width=92 style='border-top:none;border-left:none;
width:69pt'>surname</td>
<td class=xl7929100 style='border-top:none;border-left:none'>instructor name</td>
<td class=xl8129100 style='border-top:none'>grade</td>
I want to retrieve only one row from this html file to control my own grade. I get the source of the html by using java but now how can I reach the row that I want? I will find the surname first. In this part of the table how can I reach the grade coloumn?
here is my code;
import java.net.*;
import java.io.*;
public class staj {
public static void main(String[] args) throws Exception {
URL staj = new URL("http://www.cs.bilkent.edu.tr/~sekreter/SummerTraining/2014G/CS399.htm");
BufferedReader in = new BufferedReader(new InputStreamReader(staj.openStream()));
String inputLine;
String grade;
while ((inputLine = in.readLine()) != null){
if(inputLine.contains(mysurname))
//grade = WHAT?
}
in.close();
}
And also, is using java efficient and appropriate for this aim? Which language would be better?
You should definitely use Jsoup library to extract what you need from HTML document - http://jsoup.org/
I've created a sample code that demonstrates an example of extracting data from the table you provided in a description: https://gist.github.com/wololock/15f511fd9d7da9770f1d
public static void main(String[] args) throws IOException {
String url = "http://www.cs.bilkent.edu.tr/~sekreter/SummerTraining/2014G/CS399.htm";
String username = "Samet";
Document document = Jsoup.connect(url).get();
Elements rows = document.select("tr:contains("+username+")");
for (Element row : rows) {
System.out.println("---------------");
System.out.printf("No: %s\n", row.select("td:eq(0)").text());
System.out.printf("Evaluator: %s\n", row.select("td:eq(4)").text());
System.out.printf("Status: %s\n", row.select("td:eq(5)").text());
}
}
Take a look on this:
document.select("tr:contains("+username+")");
Jsoup allows you to use jquery-like methods and selectors to extract data from html documents. In this example selector you extracts only those tr elements that contain given username in nested elements. When you have a list of those rows you can simply extract the data. Here we use:
row.select("td:eq(n)")
where :eq(n) means select n-th td element nested in tr. Here is the output:
---------------
No: 85
Evaluator: Buğra Gedik
Status: E
---------------
No: 105
Evaluator: Çiğdem Gündüz Demir
Status: E
I have a very peculiar problem. I am developing a web application in Java and Spring MVC. I have a row that can be duplicated dynamically by the user on the press of a button. Each row has around 10 fields. I am binding these rows as list of objects in the backing bean and initializing this list as a lazy list in the bean. Now, it has been working fine till now but the user tried to enter 12 rows and on the 12th row, i.e., the 11th iteration(the iteration starting from 0), the 5th field becomes empty, although the user enters values and all the other fields retain their values. Since the binding happens with name, I have checked the name of the field, it is consistent with the rest of the fields in the same row and the rest of the rows. I am unable to debug and rectify the issue. This is affecting the code in production.
I can provide whatever code snippets are required.
Can somebody please help me with this. Thanks in advance.
EDIT: I tried executing the same code on a different server and it works fine there but still persists on the live server. And the problem seems to be only in the 11th iteration's 5th field. Could it be a problem with the server
Adding code:
JSP:
<c:forEach items="${addProposal.requirements}" var="req" varStatus="status">
<!--Rest of the fields-->
<form:input path="requirements[${status.index}].sampleSize" id="r_sample${status.index}" value="${addProposal.requirements[status.index].maximumFeasibility}" class="inptform2" style="width:65px;" size="10" onchange="functions();"/>
<!--Rest of the fields-->
<td width="57" align="left" valign="middle" id="btn-close" class="btn-remove">' +
'<a href="javascript:void(0)"><img src="images/btncross.png" width="18" height="17" border="0" />' +
'</a>
</td>
</c:forEach>
Javascript:
$(document).ready(function(){
//Add more dynamic rows
$("#addMore").click(function() {
var tr_temp=$("#requirement tr:first").clone();
//rest of the fields code
tr_temp.find("#r_sample0").each(function() {
$(this).attr({
'id': function(_, id) { return 'r_sample' + i},
'name': function(_, name) { return 'requirements[' + i + '].sampleSize'},
'value': ''
});
}).end();
tr_temp.find("td:last").remove();
tr_temp.append(btn_close);
tr_temp.appendTo("#requirement");
i++;
});
//To remove a dynamically added row
$("#btn-close").live('click',function(){
doNotDel=false;
count=0;
//To fetch the values of the Input Fields
$(this).parent().find("input").each(function(){
count++;
var value = $(this).val();
var id=$(this).attr('id');
if(id.indexOf("r_total")==-1){
//Skip the minutes and currency column
if(id.indexOf("minutes")==-1 && id.indexOf("currencyValF")==-1 && id.indexOf("currencyVal")==-1){
if(value!=""){
doNotDel=true;
return false; //breaks the .each loop
}
}
}
});
if(doNotDel==false){
$(this).parent().remove();
}
});
});
Bean:
private List<RequirementBean> requirements;
//in constructor
requirements = LazyList.decorate(
new ArrayList<RequirementBean>()
, new InstantiateFactory(RequirementBean.class));
Controller:
#RequestMapping(value="/addProposal", method=RequestMethod.POST)
public String addProposal(#ModelAttribute("addProposal") ProposalBean proposal, ModelMap model){
RequirementBean req;
List<RequirementBean> reqmtList;
System.out.println("Before empty rows");
reqmtList = proposal.getRequirements();
for(int i=0; i<reqmtList.size(); i++){
req = reqmtList.get(i);
if(req.getCountry()!=null){
System.out.println("sample size " + i + " :" + req.getSampleSize());
}
}
}
EDIT:
I tried changing the value of the 4th row in the same column, and now the code seems to work. I am still not able to understand what is the issue.
Hope this gives more clarity. Please help me.
I am trying to store the results of my query in a string, and print them to the bottom of my JSP page by passing that string to it. Right now, the JSP page displays fine initially, but nothing is happening when I click the button to post the command. Earlier when I accessed the servlet from an html page, and printed all my output to out using a PrintWriter, I got the results to display, but they would display on a separate page.
1) Is it a good idea to store out in this way, or should I make it something different than a string?
2) How do I get the results of the query to post to the JSP page?
databaseServlet.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
#SuppressWarnings("serial")
public class databaseServlet extends HttpServlet {
private Connection conn;
private Statement statement;
public void init(ServletConfig config) throws ServletException {
try {
Class.forName(config.getInitParameter("databaseDriver"));
conn = DriverManager.getConnection(
config.getInitParameter("databaseName"),
config.getInitParameter("username"),
config.getInitParameter("password"));
statement = conn.createStatement();
}
catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String out = "\n";
String query = request.getParameter("query");
if (query.toString().toLowerCase().contains("select")) {
//SELECT Queries
try {
ResultSet resultSet = statement.executeQuery(query.toString());
ResultSetMetaData metaData = resultSet.getMetaData();
int numberOfColumns = metaData.getColumnCount();
for(int i = 1; i<= numberOfColumns; i++){
out.concat(metaData.getColumnName(i));
}
out.concat("\n");
while (resultSet.next()){
for (int i = 1; i <= numberOfColumns; i++){
out.concat((String) resultSet.getObject(i));
}
out.concat("\n");
}
}
catch (Exception f) {
f.printStackTrace();
}
}
else if (query.toString().toLowerCase().contains("delete") || query.toLowerCase().contains("insert")) {
//DELETE and INSERT commands
try {
conn.prepareStatement(query.toString()).executeUpdate(query.toString());
out = "\t\t Database has been updated!";
}
catch (Exception l){
l.printStackTrace();
}
}
else {
//Not a valid response
out = "\t\t Not a valid command or query!";
}
RequestDispatcher dispatcher = request.getRequestDispatcher("/dbServlet.jsp");
dispatcher.forward(request, response);
request.setAttribute("queryResults", out);
}
}
dbServlet.jsp
<?xml version = "1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- dbServlet.html -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>MySQL Servlet</title>
<style type="text/css">
body{background-color: green;}
</style>
</head>
<body>
<h1>This is the MySQL Servlet</h1>
<form action = "/database/database" method = "post">
<p>
<label>Enter your query and click the button to invoke a MySQL Servlet
<textarea name = "query" cols="20" rows="5"></textarea>
<input type = "submit" value = "Run MySQL Servlet" />
<input type = "reset" value = "Clear Command" />
</label>
</p>
</form>
<hr>
<%=
request.getAttribute("queryResults");
%>
</body>
</html>
dispatcher.forward(request, response);
request.setAttribute("queryResults", out);
It should be like this
request.setAttribute("queryResults", out);
dispatcher.forward(request, response);
Before the request is dispatched the attributes has to be set
1) Is it a good idea to store out in this way, or should I make it something different than a string?
Since this is tabular data, I'd use something that preserves that structure, so that the JSP can piece it apart easily for customized formatting. Bold headers, putting it in an HTML table and stuff. Either some custom bean, or maybe just a List<String[]>.
2) How do I get the results of the query to post to the JSP page?
What you are doing now (request.setAttribute) should work. However, you need to set the attribute before you forward the request.
You could then print the String you now have like this:
<%= request.getAttribute("queryResults") %>
Or if you go with a table-structure
<% List<String[]> rows = request.getAttribute("queryResults"); %>
and then loop over that.
1) Is it a good idea to store out in this way, or should I make it something different than a string?
NO. Don't mix the presentation logic in Java code. Leaverage your JSP for that purpose I would advice you to use JAVA objects and store the row wise values in one object instance. Put all the objects in a collection and use the same in JSP for display. Same goes with column names.
2) How do I get the results of the query to post to the JSP page?
In your current format of queryResults, just print the results using = operator or out.println method in your JSP as:
<hr>
<%=request.getAttribute("queryResults"); %>
or
<% out.println(request.getAttribute("queryResults"));%>
But if you decide t use collection as adviced in answer1, then get the collection back from the request, iterate and print the results, e.g. if you decide to use List<String[]> where String[] maps one row data then:
<TABLE id="results">
<% List<String> columns = (List<String>)request.getAttribute("queryColumns");
List<String[]> results = (List<String[]>)request.getAttribute("queryResults");
out.println("<TR>");
for(String columnName: columns ){
out.println("<TD>"+columnName+"</TD>");
}
out.println("</TR>");
//print data
for(String[] rowData: results){
out.println("<TR>");
for(String data: rowData){
out.println("<TD>"+data+"</TD>");
}
out.println("</TR>");
}
%>
</TABLE>
I have a form like this :
<form id="test" name="test" action="/pages/font/getFontTitle.jsp" method="POST" enctype="multipart/form-data">
<div class="dialog">
<table>
<tbody>
<tr class="prop"><td valign="top">Name</td><td><input type="text" name="name"></td></tr>
<tr class="prop"><td valign="top"><input type="file" name="fname" size="62" value="" id="fname"/></td><td><span class="button"><s:submit/></span></td></tr>
</tbody>
</table>
</div>
</form>
And my servlet look like this :
String contentType=request.getContentType(),Location="0.";
out.println("Done");
System.out.println("contentType = "+contentType);
boolean isMultipart=ServletFileUpload.isMultipartContent(request); // Check that we have a file upload request
System.out.println("isMultipart = "+isMultipart);
int formDataLength=request.getContentLength(); // We are taking the length of Content type data
byte dataBytes[]=new byte[formDataLength];
System.out.println("dataBytes = "+dataBytes.length+"\n"+dataBytes.toString());
java.util.Map<java.lang.String,java.lang.String[]> ParameterMap=request.getParameterMap();
Iterator it=ParameterMap.entrySet().iterator();
while (it.hasNext())
{
Map.Entry pair=(Map.Entry)it.next();
System.out.println(pair.getKey()+" = "+(pair.getValue()).toString());
// it.remove(); // avoids a ConcurrentModificationException
}
System.out.println("request = \n"+request.getParameterNames().toString());
if (isMultipart)
{
FileItemFactory factory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(factory);
List items=null;
Location+="1.";
try { items=upload.parseRequest(request); }
catch (FileUploadException e) { e.printStackTrace(); }
Location+="2.";
Iterator itr=items.iterator();
Location+="3.";
while (itr.hasNext())
{
Location+="4.";
FileItem item=(FileItem)itr.next();
if (item.isFormField())
{
String name=item.getFieldName(),value=item.getString();
System.out.println("name = "+name+" value = "+value);
Location+="5.";
}
else
{
try
{
Location+="6.";
String itemName=item.getName(),savedFilePath=itemName;
File savedFile=new File(savedFilePath);
System.out.println("savedFile = "+savedFile.getAbsolutePath());
item.write(savedFile);
}
catch (Exception e) { e.printStackTrace(); }
}
}
}
Location+="e.";
out.println(" [ "+Location+" ]");
out.flush();
The result I get was :
contentType = multipart/form-data; boundary=---------------------------15890672924370
isMultipart = true
dataBytes = 35909
[B#14d3ba9
name = [Ljava.lang.String;#187f9d7
request =
java.util.Vector$1#23ca6e
dataBytes has a file in it, but it never got into the while (itr.hasNext()) loop, the jsp output was : Done [ 0.1.2.3.e. ] , Location 4,5,6 was never reached.
[1] Why ?
[2] How to turn "dataBytes = [B#14d3ba9 " into something readable or a file ?
[3] How to turn "name = [Ljava.lang.String;#187f9d7" into the original string value ?
[4] I'm using "(pair.getValue()).toString()", but why it's not a readable string ?
The client will send the HTTP request body only once.
Your code is however trying to read the request body twice. The first time by the getParameterMap() call:
java.util.Map<java.lang.String,java.lang.String[]> ParameterMap=request.getParameterMap();
and the second time by Apache Commons FileUpload (which will face an empty request):
try { items=upload.parseRequest(request); }
This isn't going to work.
Use either the standard Servlet API methods, or Apache Commons FileUpload exclusively.
See also:
How to upload files to server using JSP/Servlet? - contains concrete examples of both the Commons FileUpload and standard Servlet API methods.
use should use servelt 3.0 spec and annotate your servlet accordingly and then usin can user request.getParts() with all the multi-part data. Read about it.
Subquestion 1,3,4: if you cannot use the file upload feature added in Servlet 3.0 I think you're better off using Commons Fileupload, more or less the de facto standard for uploading files to servlets. It's robust, well tested and just works.
Subquestion 2: the Javadoc for ServletRequest's getParameterMap states:
Returns: an immutable java.util.Map containing parameter names as keys
and parameter values as map values. The keys in the parameter map are
of type String. The values in the parameter map are of type String
array.
Emphasis added: the values returned are arrays of Strings, not Strings. That's why you get the strange output value. Try
System.out.println( pair.getKey()+" = "+ pair.getValue()[0] );
But also consider using a logger in your servlets, it's better practice than dumping stuff in System.out
ps: use the code formatting feature that's probaby available in your IDE, your code is pretty hard to read.