JSP helper class for printing content - java

I have a question on code reuse in JSP. I have a JSP page example.jsp that issues a call to a database and gets the results. I have a java class HelperClass.java that accepts a record and prints out the different fields
response.getWriter().println
Now my JSP page has HTML as well and the problem is the content printed out by the HelperClass appears before the content in the JSP page. E.g.
<body>
This is the first line <br/>
HelperClass.printdata("second line");
</body>
output is
secondline This is the first line
Is this a known issue. What is the best way to design an HelperClass for a JSP page that prints content out to the page. Any pointers would be greatly appreciated.

Just do not use a "HelperClass to print data". This makes no sense. There you have EL for.
${bean.property}
That's all. Use a servlet to control, preprocess and postprocess requests. Use taglibs (e.g. JSTL) and EL to access and display backend data.
Here's a basic kickoff example of a Servlet which preprocesses the request before display in JSP:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Person> persons = personDAO.list(); // Get list of persons from DB.
request.setAttribute("persons", persons); // So it's available as `${persons}` in EL.
request.getRequestDispatcher("/WEB-INF/persons.jsp").forward(request, response); // Forward to JSP for display.
}
Here, the Person is just a Javabean class which represents a real world entity.
public class Person {
private Long id;
private String name;
private String email;
private Integer age;
// Add/generate getters and setters here.
}
The PersonDAO#list() method just returns a List of Person objects from the DB:
public List<Person> list() throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<Person> persons = new ArrayList<Person>();
try {
connection = database.getConnection();
statement = connection.createStatement("SELECT id, name, email, age FROM person");
resultSet = statement.executeQuery();
while (resultSet.next()) {
Person person = new Person();
person.setId(resultSet.getLong("id"));
person.setName(resultSet.getString("name"));
person.setEmail(resultSet.getString("email"));
person.setAge(resultSet.getInteger("age"));
persons.add(person);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return persons;
}
Map the servlet in web.xml on an url-pattern of /persons. The JSP is hidden in /WEB-INF so that nobody can access it directly without requesting the servlet first (else one would get an empty table).
Now, here's how persons.jsp look like, it uses JSTL (just drop jstl-1.2.jar in /WEB-INF/lib) c:forEach to iterate over a List and it uses EL to access the backend data and bean properties. The servlet has put the List<Person> as request attribute with name persons so that it's available by ${persons} in EL. Each iteration in c:forEach gives a Person instance back, so that you can display their proeprties with EL.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<table>
<c:forEach items="${persons}" var="person">
<tr>
<td>${person.name}</td>
<td>${person.email}</td>
<td>${person.age}</td>
</tr>
</c:forEach>
</table>
Call it by http://example.com/contextname/persons. That's all. No need for a "HelperClass to print data" ;) To learn more about JSTL, check Java EE tutorial part II chapter 7 and to learn more about EL, check Java EE tutorial part II chapter 5. To learn more about stuff behind PersonDAO, check this article.

Related

Calling bean method on jsp

I'm trying to call a method that connects that is on a Bean on a jsp file. The method will make a request to a RMI Server and return a string. At this point the method is just return a pre-defined string for test.
This is the bean method:
public String getListProjects() throws RemoteException {
this.dataToSend = new Object[2];
this.dataToSend[1] = 0;
this.postCard = new ClientRequest("2", this.dataToSend, "tempo");
try{
this.postCard = this.connectToRMI.getActualProjects(this.postCard);
}catch(Exception e){
e.printStackTrace();
}
return "Hello";
}
And this is the jsp code:
<h1>Projectos Actuais</h1>
<h2><%
fundstarter.model.ConnectToRMIBean aux = new fundstarter.model.ConnectToRMIBean();
try{
aux.getListProjects();
}catch(Exception e){
e.printStackTrace();
}
%>
</h2>
I'm guiding my self from another code, and the method is called like this. But in my case it's not working, and I can't figure out what is wrong.
Since you've tagged this struts2, assuming the getListProjects() is on the Action, in JSP use:
<s:property value="listProjects" />
If instead it is on a bean, declare the bean in the Action, and expose it through a getter:
private MyBean bean;
public MyBean getBean(){
return bean;
}
and in JSP use the dot notation:
<s:property value="bean.listProjects" />
P.S: always avoid Scriptlets (<% %>), they're evil.
Quoting and fixing your latest change on edit with some comments:
<h1>Projectos Actuais</h1>
<h2><%
try{
fundstarter.model.ConnectToRMIBean aux = new fundstarter.model.ConnectToRMIBean();
//Send result into generated HTML page with out.print!
out.print(aux.getListProjects());
}catch(Exception e){
e.printStackTrace();
}
%>
</h2>
As per the flow of Struts there should be field in beanclass with same name of getter & setter. For an example if your method name is getListPorjects then in your bean class there should be a private string variable name listprojects.
Also your method will update with following to way to return listprojects.
example:
public String getListProjects() throws RemoteException {
this.dataToSend = new Object[2];
this.dataToSend[1] = 0;
this.postCard = new ClientRequest("2", this.dataToSend, "tempo");
try{
this.postCard = this.connectToRMI.getActualProjects(this.postCard);
listprojects = "hello"
}catch(Exception e){
e.printStackTrace();
}
return listprojects;
}
Calling bean variable should be with ID over the JSP page.
<jsp:useBean id="aux" class="com.path.to.ConnectToRMIBean" scope="request" />
----
yours stuff
-----
<h1>${aux.listProjects}
hope this will help you. good luck
You are just missing the way <% %> and <%= %> are used in JSP. to print in <% %> tags use
<% out.println("Your results"); %>
and for <%= %>
<%=
String.valueOf(1+2);
%>

JSP/JSTL - Unable to display information to the browser

Background:
I wrote a previous servlet that created dynamic webpages where it would read and write to a MySQL database. When I would read from it, I stored the result in a ResultSet, then displayed this information. Everything worked and I was told I should re-write it using JSPs and JSTLs. To do this, in my servlet, I created a ResultSet and stored each column's result in a separate ArrayList. In my JSP, I'm trying to iterate through the ArrayLists, however, the webpage is blank. Since I'm using NetBeans, it normally will indicate any errors, but there seem to be none, so I'm guessing there's either a logical error or a run-time error (which doesn't exactly narrow it down). I've tried simply printing the size of an ArrayList but even that isn't displaying! My guess is either the ArrayList is never populated or it's not properly being sent to the JSP.
To note, my database is populated and I am able to write to it. I've looked throughout various websites to see if anything can help but nothing has so far. I also went through my lecture notes and my syntax seems to be correct.
As part of the assignment, we are required to write all servlet code in processRequest(request, response). doPost and doGet both call this method.
My Servlet:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html;charset=UTF-8");
ResultSet res = null;
ArrayList<String> bookIDs, bookTitles, bookAuthors;
DBUtil util = new DBUtil();
try {
res = BookDB.showBooks();
bookIDs = new ArrayList<String>();
bookTitles = new ArrayList<String>();
bookAuthors = new ArrayList<String>();
while(res.next()) {
bookIDs.add(res.getString("bookID"));
bookTitles.add(res.getString("title"));
bookAuthors.add(res.getString("author"));
}
request.setAttribute("IDHolder", bookIDs);
request.setAttribute("titlesHolder", bookTitles);
request.setAttribute("authorHolder", bookAuthors);
RequestDispatcher booksDispatcher = request.getRequestDispatcher("jspShowAll.jsp");
booksDispatcher.forward(request, response);
} catch (SQLException sqle) {
Logger.getLogger(ShowAllBooks.class.getName()).log(Level.SEVERE, null, sqle);
} catch (IOException iox) {
Logger.getLogger(ShowAllBooks.class.getName()).log(Level.SEVERE, null, iox);
} catch (ServletException ex) {
Logger.getLogger(ShowAllBooks.class.getName()).log(Level.SEVERE, null, ex);
}
}
ResultSet Creation (in a separate package):
public static ResultSet showBooks() throws SQLException {
ConnControl myConnPool=new ConnControl();
Statement s=null;
ResultSet res=null;
Connection myConn=myConnPool.connect();
String queryStm= "SELECT * FROM books;";
s=myConn.createStatement();
res = s.executeQuery(queryStm);
return res;
}
This method was copied and pasted from my previous web app, which works perfectly. The table and database are the same.
My JSP:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
</head>
<body>
<c:forEach var="ids" items="${IDHolder}">
<p>${ids}</p>
</c:forEach>
<c:forEach var="titles" items="${titlesHolder}">
<p>${titles}</p>
</c:forEach>
<c:forEach var="authors" items="${authorHolder}">
<p>${authors}</p>
</c:forEach>
</body>
</html>
My Java Bean:
public class Book {
private int id;
private String title;
private String author;
public Book() {
}
public Book(int id, String title, String author) {
this.id = id;
this.title = title;
this.author = author;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
}
After reviewing the logs and calling printStackTrace() for each exception thrown, I found I overlooked the simplest thing. I forgot to include the JSTL library! Now that I did, I ran my JSP again and it displayed properly.

Run multiple function using JSP

i am new to web programming. i am trying to connect database using jsp with odbc. i have already written a java code for this. now i need to run on Tomcat server. so i choose JSP to do this job.But this is showing me void type not allowed here and erors. how to run this code using jsp. what are my mistakes. please help me to solve in this.
now this is my code
<%#page import="java.sql.*"%>
<%#page import="java.util.*" %>
<%#page import="java.util.logging.Level"%>
<%#page import="java.util.logging.Logger"%>
<%!
int i=0,j=0,k=0;
Connection conn=null;
Connection connection=null;
static int count=0;
String Cname[]=null;
String Title[]=null;
Statement stmt1=null;
ResultSet NumOfRows=null;
Statement stmt2=null;
ResultSet SpreadsheetValues=null;
Statement stmt3=null;
ResultSet rs3=null;
int RowCount;
//this static function required to connect excel database
static
{
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Exception in connecting to DB"+e.getMessage());
}
}
// connect Sql database
void ConnectSqlDB() {
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection("jdbc:odbc:ServerDB","sa","sqladmin");
System.out.println("MSSQL connected " +"<br>");
}catch(Exception e){
e.printStackTrace();
System.out.println("Exception in connecting to DB"+e.getMessage());
}
}
void ConnectExcelDB() throws SQLException{
conn=DriverManager.getConnection("jdbc:odbc:spreadsheetdb","","");
}
void getRowcount() throws SQLException{
stmt1=conn.createStatement();
String Qs1="select count(*) from [Sheet1$]";
NumOfRows=stmt1.executeQuery(Qs1);
while(NumOfRows.next()){
Rowcount=NumOfRows.getInt(1);
}
NumOfRows.close();
}
void getExcelValues() throws SQLException{
stmt2=conn.createStatement();
String Qs2="select * from [Sheet1$]";
SpreadsheetValues=stmt2.executeQuery(Qs2);
Cname=new String[Rowcount];
Title=new String[Rowcount];
while(SpreadsheetValues.next()){
// Assigning Spread sheet values to String array
Cname[j]=SpreadsheetValues.getString("Cname");
Title[j]=SpreadsheetValues.getString("Title");
j++;
}
}
SpreadsheetValues.close();
stmt2.close();
conn.close();
SpreadsheetValues=null;
stmt2=null;
conn=null;
}
%>
<%=ConnectSqlDB()%>
<%=ConnectExcelDB()%>
<%=getRowcount()%>
<%=getExcelValues()%>
When you are using a method in a JSP Expression, then your method should return a value. I see all of your methods have a return type of void i.e. returning nothing. Change your methods to return appropriate value.
NOTE
I understand that you are currently learning JSP etc but keep in mind that writing contorl/application logic in a view technology like JSP is a bad practice. Try reading the MVC pattern.
Do not use <%= %> (Expression) to invoke void methods and you should have to avoid Java code in JSP (read SO thread).
<%
ConnectSqlDB();
ConnectExcelDB();
getRowcount();
getExcelValues();
%>
<p>Total Records : <%=RowCount%>
<p>Array element at 0 index <%=name[0]%>
<%
for(String v:name)
{
out.println("<br/>" + v);
}
%>

How to call a static method in JSP/EL?

I'm new to JSP. I tried connecting MySQL and my JSP pages and it works fine. But here is what I needed to do.
I have a table attribute called "balance". Retrieve it and use it to calculate a new value called "amount". (I'm not printing "balance").
<c:forEach var="row" items="${rs.rows}">
ID: ${row.id}<br/>
Passwd: ${row.passwd}<br/>
Amount: <%=Calculate.getAmount(${row.balance})%>
</c:forEach>
It seems it's not possible to insert scriptlets within JSTL tags.
You cannot invoke static methods directly in EL. EL will only invoke instance methods.
As to your failing scriptlet attempt, you cannot mix scriptlets and EL. Use the one or the other. Since scriptlets are discouraged over a decade, you should stick to an EL-only solution.
You have basically 2 options (assuming both balance and Calculate#getAmount() are double).
Just wrap it in an instance method.
public double getAmount() {
return Calculate.getAmount(balance);
}
And use it instead:
Amount: ${row.amount}
Or, declare Calculate#getAmount() as an EL function. First create a /WEB-INF/functions.tld file:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<display-name>Custom Functions</display-name>
<tlib-version>1.0</tlib-version>
<uri>http://example.com/functions</uri>
<function>
<name>calculateAmount</name>
<function-class>com.example.Calculate</function-class>
<function-signature>double getAmount(double)</function-signature>
</function>
</taglib>
And use it as follows:
<%#taglib uri="http://example.com/functions" prefix="f" %>
...
Amount: ${f:calculateAmount(row.balance)}">
Another approach is to use Spring SpEL:
<%#taglib prefix="s" uri="http://www.springframework.org/tags" %>
<s:eval expression="T(org.company.Calculate).getAmount(row.balance)" var="rowBalance" />
Amount: ${rowBalance}
If you skip optional var="rowBalance" then <s:eval> will print the result of the expression to output.
If your Java class is:
package com.test.ejb.util;
public class CommonUtilFunc {
public static String getStatusDesc(String status){
if(status.equals("A")){
return "Active";
}else if(status.equals("I")){
return "Inactive";
}else{
return "Unknown";
}
}
}
Then you can call static method 'getStatusDesc' as below in JSP page.
Use JSTL useBean to get class at top of the JSP page:
<jsp:useBean id="cmnUtilFunc" class="com.test.ejb.util.CommonUtilFunc"/>
Then call function where you required using Expression Language:
<table>
<td>${cmnUtilFunc.getStatusDesc('A')}</td>
</table>
Bean like StaticInterface also can be used
<h:commandButton value="reset settings" action="#{staticinterface.resetSettings}"/>
and bean
package com.example.common;
import com.example.common.Settings;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean(name = "staticinterface")
#ViewScoped
public class StaticInterface {
public StaticInterface() {
}
public void resetSettings() {
Settings.reset();
}
}
EL 2.2 has inbuild mechanism of calling methods. More here: oracle site.
But it has no access to static methods. Though you can stil call it's via object reference. But i use another solution, described in this article: Calling a Static Method From EL
If you're using struts2, you could use
<s:var name='myVar' value="%{#package.prefix.MyClass#myMethod('param')}"/>
and then reference 'myVar' in html or html tag attribute as ${myVar}
Based on #Lukas answer you can use that bean and call method by reflection:
#ManagedBean (name = "staticCaller")
#ApplicationScoped
public class StaticCaller {
private static final Logger LOGGER = Logger.getLogger(StaticCaller.class);
/**
* #param clazz
* #param method
* #return
*/
#SuppressWarnings("unchecked")
public <E> E call(String clazz, String method, Object... objs){
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final List<Class<?>> clasesparamList = new ArrayList<Class<?>>();
final List<Object> objectParamList = new ArrayList<Object>();
if (objs != null && objs.length > 0){
for (final Object obj : objs){
clasesparamList.add(obj.getClass());
objectParamList.add(obj);
}
}
try {
final Class<?> clase = loader.loadClass(clazz);
final Method met = clase.getMethod(method, clasesparamList.toArray(new Class<?>[clasesparamList.size()]));
return (E) met.invoke(null, objectParamList.toArray());
} catch (ClassNotFoundException e) {
LOGGER.error(e.getMessage(), e);
} catch (InvocationTargetException e) {
LOGGER.error(e.getMessage(), e);
} catch (IllegalAccessException e) {
LOGGER.error(e.getMessage(), e);
} catch (IllegalArgumentException e) {
LOGGER.error(e.getMessage(), e);
} catch (NoSuchMethodException e) {
LOGGER.error(e.getMessage(), e);
} catch (SecurityException e) {
LOGGER.error(e.getMessage(), e);
}
return null;
}
}
xhtml, into a commandbutton for example:
<p:commandButton action="#{staticCaller.call('org.company.Calculate', 'getAmount', row.balance)}" process="#this"/>
<c:forEach var="row" items="${rs.rows}">
ID: ${row.id}<br/>
Passwd: ${row.passwd}<br/>
<c:set var="balance" value="${row.balance}"/>
Amount: <%=Calculate.getAmount(pageContext.getAttribute("balance").toString())%>
</c:forEach>
In this solution, we're assigning value(Through core tag) to a variable and then we're fetching value of that variable in scriplet.
In Struts2 or Webwork2, you can use this:
<s:set name="tourLanguage" value="#foo.bar.TourLanguage#getTour(#name)"/>
Then reference #tourLanguage in your jsp

Object suddenly missing from HttpServletRequest

I print a list directly in the servlet using the print writer and the list prints.
When I try to put in the jsp however the list doesn't print whether I use JSTL or scriptlets.
I tried to test in JSTL and scriptlet if the object is null and turns out that it is!
Why does this happen and how can I fix this?
Servlet code that works
for (Artist artist:artists){
resp.getWriter().println(artist.getName());
}
Servlet code that puts object in the request
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("com/helloworld/beans/helloworld-context.xml");
ArtistDao artistDao = (ArtistDao) ctx.getBean("artistDao");
List<Artist> artists = null;
try {
artists = artistDao.getAll();
} catch (SQLException e) {
e.printStackTrace();
}
req.setAttribute("artists", artists);
try {
req.getRequestDispatcher("index.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
}
scriptlet code that suddenly finds the object null
<%
List<Artist> artists = (List<Artist>) request.getAttribute("artists");
if (artists == null) {
out.println("artists null");
}
else {
for (Artist artist: artists){
out.println(artist.getName());
}
}
%>
Even the jstl code seems to agree
<c:if test="${artists eq null}">
Artists are null
</c:if>
<c:forEach var="artist" items="${artists}">
${artist.name}
</c:forEach>
For my app I am using weblogic, spring 2.5.6 and ibatis.
I think it depends on the web server. But without changing your previous directory structure,
try putting the list in session like this
req.getSession(false).setAttribute("artists", artists);
and in your jsp,
write
List<Artist> artists = (List<Artist>) request.getSession(false).getAttribute("artists");
I think my approach will work for all web servers.
Maybe the app server is resetting your request object. You can work around this by creating a new request object, that wraps your original request, and pass that to the reqest dispatcher.
e.g.
MyHttpRequest myRequest = new MyHttpRequest(req);
myRequest.setAttribute(...);
req.getRequestDispatcher("index.jsp").forward(myRequest, resp);
And the MyHttpReqest code:
class MyHttpRequest extends HttpServletRequestWrapper
{
Map attributes = new HashMap();
MyHttpRequest(HttpRequest original) {
super(original);
}
#Override
public void setAttribute(Object key, Object value) {
attributes.put(key, value);
}
public Object getAttribute(Object key) {
Object value = attributes.get(key);
if (value==null)
value = super.getAttribute(key);
return value;
}
// similar for removeAttribute
}
I just discovered inadvertently while trying to fix my directory structure in WebContent/
My previous directory structure was
WEB-CONTENT/
- META-INF/
- WEB-INF/
index.jsp
Then I tried to create a folder jsp in WEB-CONTENT and placed index.jsp there. It works!
My current directory structure now is
WEB-CONTENT/
- META-INF/
- WEB-INF/
- jsp/
-index.jsp
I don't know why it works but it did.
Anyone here with any idea why?

Categories

Resources