Access java <List> from from jsp / jstl MVC app - java

I have been finding it difficult to understand where I am going wrong. I understand that we should move with the times but I am not sure how to replace a scriptlet, that I can get to do the job, with the JSTL taglibrary functions.
I have a Model class called Ranges.class which contains a rangeName (String) and a startRange (BigDecimal) and an endRange (BigDecimal) value. I have a DAO class that handles all the db queries (crud type methods). I have a method in RangesDao.class called getAllRanges() which will get all the potential ranges from a mysql db and return a List. This will fetch all the Range objects which include the rangeName, startRange and endRange.
Q: So basically what I want to do is from my jsp page when a text input is selected I want to check if it is between the start and end value of each Range object (that was returned in the List) and when I have a match I want to update a different text input with that objects rangeName value.
This is what I have so far.
Range.class
package za.co.zs6erb.model;
import java.math.BigDecimal;
public class Range {
private int range_id;
private String rangeName;
private BigDecimal startRange;
private BigDecimal endRange;
//...getters and setters for each of the above variables ...
#Override
public String toString() {
return "Ranges [range_id=" + range_id + ", Range Name=" + rangeName + ", Start Range=" + startRange
+ ", End Range=" + endRangeBand + "]";
}
}
DAO Class: This is the getAllRanges() method
public List<Range> getAllRanges() {
List<Range> rangeList = new ArrayList<Range>();
try {
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("select * from ranges order by range_id");
while (rs.next()) {
Range lRange = new Range();
lRange.setID(rs.getInt("range_id"));
lRange.setRangeName(rs.getString("rangeName"));
lRange.setStartRange(rs.getBigDecimal("start_range"));
lRange.setEndRange(rs.getBigDecimal("end_range"));
rangeList.add(lRange);
}
} catch (SQLException e) {
e.printStackTrace();
}
return rangeList;
}
Controller: This class has a doGet() and a doPost() method the piece I am busy with is the doGet(). The doPost() is used when adding a "plannedRoute" object (just an object that has several other attributes that need to be added to a different table. - not the issue here) From the doGet() I list all the "plannedRoute" objects which all have one Range associated with each. When adding a new route I launch a jsp page from the doGet() method. The following part should make things a little clearer.
doGet():
private static String LIST_PLANNEDROUTES = "plannedroutes.jsp";
private RangeDao rDao;
//Constructor
public PlannedRouteController() {
super();
rDao = new RangeDao();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String forward = "";
String action = request.getParameter("action");
if (action.equalsIgnoreCase("new")) {
forward = LIST_PLANNEDROUTES;
request.setAttribute("rd", rDao);
}
RequestDispatcher view = request.getRequestDispatcher(forward);
view.forward(request, response);
}
So now we have the crux of the issue ...
plannedRoutes.jsp
<%# page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>MyTest</title>
<script src="sj/jquery.js"></script>
<script type="text/javascript">
//<!--
$(document).ready(function(){
$("#range").change(function() {
alert("A Range was entered");
<c:forEach var="entry" items="${rd}">
alert( "HERE>" + ${entry.rangeName});
</c:forEach>
document.getElementById("testName").value = $("#range").val();
});
});
//-->
</script>
</HEAD>
<BODY>
<form method="POST" action='<form method="POST" action='ContactController' name="frmAddContact">' name="frmAddRoute">
Range: <input type="text" id="range" name="range" />
Name: <input type="text" id="testName" name="testName" readonly />
<!-- a whole bunch of other stuff here -->
</form>
</BODY>
</HTML>
Q: So when the value in the range input text field changes (I call the method in the tag and there I want to step through the List and match what was typed in to see if it falls between the start and end range of any of the Range Objects. When I find a match I want to be able to fetch the rangeName attribute of that object and add that to the testName input text area.
I hope this is clear enough. I have tried the without success and am not sure where to go from here without using scriptlets ... Any help would be appreciated.
Kind Regards
Sean

First, you're putting the DAO object into the request, but in the jsp you want to access the list that the DAO method would return. Call the method in your controller and put the resulting list into the request.
request.setAttribute("rd", rDao.getAllRanges());
The rest all needs to be client-side code unless you want to change your design to use ajax. Try serializing the range list, in the controller, into a JSON string. Then in your jsp, you'll be giving javascript access to the data. Let's say you're using Gson to serialize in your servlet:
request.setAttribute("rd", new Gson().toJson(rDao.getAllRanges(), List.class));
So when you access ${rd} in the jsp, it will be a String in the following form:
[{"range_id":1,"rangeName":"Range 1", "startRange":10.0, "endRange":19.99},{"range_id":2,"rangeName":"Second Range", "startRange":18.75, "endRange":29.5}]
In the jsp, you set that as a javascript variable that can be accessed by your change function.
$("#range").change(function() {
var rdArray = ${rd};
alert("A Range was entered");
var floatVal = parseFloat($("#range").val());
var rangeFound = false;
var rdSize = rdArray.length;
var index = 0;
while (index < rdSize && !rangeFound)
{
var rangeObject = rdArray[index++];
if (floatVal >= rangeObject.startRange && floatVal <= rangeObject.endRange)
{
rangeFound = true;
$('#testName').val(rangeObject.rangeName);
}
}
});

Related

How do I send data from a Controller to a JSP page in Spring?

I have two JSP pages let's just called them 1 & 2. I'm passing a latitude and longitude value from page 1 to a method in my controller class via an AJAX query in a javascript function on JSP page 1. The method in the controller will use the latitude and longitude to query a database and provide an average house price of all houses in a 1km radius of the latitude and longitude passed into the controller. I have a debug print statement that confirms that the query is successful as it prints the average house price in the Eclipse console.
If you're still with me, how can I then pass this doubleaverage house price value (housePriceAverage) from the controller method to display on JSP page number 2? For some reason, the new JSP page (number 2) simply will not load when called, however the debug works to show the values are being passed to the controller and the query works? I would really appreciate any advice/tips anyone would have!
Here's an example of the method inside my Controller class. If you wanna see the other functionality I'll be happy to include it. Thank You!
#RequestMapping(value = "/parseHousePrice", method={RequestMethod.POST, RequestMethod.GET})
public #ResponseBody String parseHousePrice(#RequestBody HousePrice housePriceObject,
#RequestParam("latitude") double latitude,
#RequestParam("longitude") double longitude,
Model model) {
// This passes the lat & long into a method that will query the database
double housePriceAverage = parseHousePrice.ParseHousePrice(latitude, longitude);
// This print statement successfully prints the results fromt he query
System.out.println("The average house price for this area is: " + housePriceAverage);
model.addAttribute("houseprice", housePriceAverage);
// JSP Page I'm trying to pass the information above to
return "houseprice";
}
Code for JSP page 2 where I want to send the data (houseprice) to, from the controller
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#page isELIgnored="false" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js">
</script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>House Price</title>
<style>
I've excluded some CSS code here for conciseness
</style>
<script>
I've excluded Javascript code for a Navbar here for conciseness
</script>
</head>
<body>
<p style="display:none">${houseprice}</p>
<p style="display:none">${housepricelistsize}</p>
</body>
Javascript function in JSP 1 that sends the latitude and longitude data to the controller
function sendDataToParseHousePrice(){
// Calculates the latitude and longitude of the user
$('.search_latitude').val(marker.getPosition().lat());
var Lat = marker.getPosition().lat();
console.log(Lat);
$('.search_longitude').val(marker.getPosition().lng());
var Long = marker.getPosition().lng();
console.log(Long);
$.ajax({
type: "POST",
url: "/parseHousePrice",
data: { latitude: Lat,
longitude: Long
}, // parameters
datatype: 'json'
});
}
Because of #ResponseBody on your method, the text houseprice is returned to page 1 as an AJAX response. It is not resolved as a view. If you want to stick to your AJAX request you can return the housePriceAverage instead. Then when you get the AJAX response on page 1 use the value to navigate to page 2. In page 2 use #RequestParam to get the housePriceAverage supplied as a parameter
#RequestMapping(value = "/parseHousePrice", method={RequestMethod.POST, RequestMethod.GET})
public double parseHousePrice(#RequestBody HousePrice housePriceObject,
#RequestParam("latitude") double latitude,
#RequestParam("longitude") double longitude,
Model model) {
// This passes the lat & long into a method that will query the database
double housePriceAverage = parseHousePrice.ParseHousePrice(latitude, longitude);
// This print statement successfully prints the results fromt he query
System.out.println("The average house price for this area is: " + housePriceAverage);
return housePriceAverage;
}
If its possible to forgo AJAX then do a conventional POST to your Controller and use view resolution to navigate to page 2. You achieve this by removing #ResponseBody
#RequestMapping(value = "/parseHousePrice", method={RequestMethod.POST, RequestMethod.GET})
public String parseHousePrice(#RequestBody HousePrice housePriceObject,
#RequestParam("latitude") double latitude,
#RequestParam("longitude") double longitude,
Model model) {
// This passes the lat & long into a method that will query the database
double housePriceAverage = parseHousePrice.ParseHousePrice(latitude, longitude);
// This print statement successfully prints the results fromt he query
System.out.println("The average house price for this area is: " + housePriceAverage);
model.addAttribute("houseprice", housePriceAverage);
// JSP Page I'm trying to pass the information above to
return "houseprice";
}

Making one of the field in Solr (URL)hyperlink [duplicate]

This question already has an answer here:
Set String to clickable URL
(1 answer)
Closed 6 years ago.
What I mean is, when the user search a particular stuff, for instance Supreme,
It will print out supremenewyork.com , Supreme, A skateboarding shop/clothing brand[1][2] established in New York City in April 1994.
How do I make the text supremenewyork.com become an URL. Basically I get the parameter from servlet and printed on a JSP result page. Based by what I know it cannot be done in the Solr side.
Any expert in Solr able to give me a solution?
Below is my following code.
System.out.println("request parameter: "
+ request.getParameter("search"));
PrintWriter out = response.getWriter();
try {
HttpSolrServer solr = new HttpSolrServer("http://localhost:8983/solr/Corename/");
SolrQuery query = new SolrQuery();
String test;
// Getting the parameter from the textbox name search
query.setQuery(request.getParameter("search"));
query.setFields("id", "content");
query.setStart(0);
QueryResponse response1 = solr.query(query);
SolrDocumentList results = response1.getResults();
for (int i = 0; i < results.size(); ++i) {
test = results.toString();
String testresults = test.replace("numFound=2,start=0,docs=[","");
testresults = testresults.replace("numFound=1,start=0,docs=[","");
testresults = testresults.replace("numFound=4,start=0,docs=[","");
testresults = testresults.replace("SolrDocument{", "");
testresults = testresults.replace("content=[", "");
testresults = testresults.replace("id=", "");
testresults = testresults.replace("]}]}", "");
testresults = testresults.replace("]}", "");
request.setAttribute("testresults", testresults);
System.out.println(testresults);
request.getRequestDispatcher("Results.jsp").forward(request,
response);
}
} catch (SolrServerException se) {
se.printStackTrace();
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
JSP Code:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>THE SUPER SEARCH</title>
</head>
<body>
<h4>Here's the following results</h4>
<%String testresults=(String)request.getAttribute("testresults");
out.print("" + testresults);
%>
</body>
</html>
I discourage to do this thing directly in Solr, IMHO it is like to ask MySql to store a string and return a url.
Anyway, if you really want do this with Solr, there are many ways:
use Solr DocTransformers
format the output of one or more fields, I suggest to use XSLTResponseWriter which can return also json.
add to your Solr instance your own SearchComponent, here is an interesting post and here.
another way I know is Alba, Solr Plugins made easy.
At last, if you really want have back a ulr, you could just store the url in a field during the indexing.
UPDATE
Looking at code you have posted, the biggest problem I see is the way you're using to iterate on the returned results set. You should do something like this:
for (SolrDocument d : response1.getResults()) {
String content = (String) d.get("content");
long id = (long) d.get("id");
}
A Solrdocument internally is a LinkedHashMap.

How to pass an array from servlet to jsp page?

I have achieved sending an integer variable to a jsp page using the following code:
resp.sendRedirect(("result.jsp?fibNum=" + fibNum));
But when I try the same to pass the array, int[] fibSequence I get the following passed to the address bar of the jsp page:
Does anyone have any advice on how I can output the array value passed over to the jsp page?`
This is how I sent the array across to the result jsp page within the doPost():
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
// read form fields
String fibNum = req.getParameter("fibNum");
try{
//Get reference from server's registry
Registry registry = LocateRegistry.getRegistry("127.0.0.1");
//Lookup server object from server's registry
IFibonacci fibonacci_proxy = (IFibonacci)registry.lookup("PowerObject");
int fibMax = Integer.parseInt(fibNum);
//Invoke server object's methods
//Get Fibonacci array.
int[] fibSequence = fibonacci_proxy.fibonacciArrayTest(fibMax);
for (int value : fibSequence) {
System.out.println(value);
}
//System.out.println(Arrays.toString(fibSequence));
}catch(NotBoundException nbe){
nbe.printStackTrace();
}catch(RemoteException re){
re.printStackTrace();
}
//send input to the result page using a redirect
//resp.sendRedirect(("result.jsp?fibNum=" + fibNum));
resp.sendRedirect(("result.jsp?fibSequence=" + fibSequence));
}
How I've tried to retrieve the array values on the jsp page and print them, but I'm getting a fibSequence cannot be resolved to a variable although this is the name of the array passed over:
Return to Main<br>
<%String[] var_array=request.getParameterValues("fibSequence");%>
<%System.out.print(""+fibSequence);%>
</form>
Trust the compiler. fiBSeq ist not defined. You defined fibSequence. But passing that array as an argument will not work, because you will pass (int[]).toString() which is probably not what you want. You can serialize and encode it, if it is not too big. Or post it.
EDIT 1
int [] array = {1,2,3,4,5,6,7,8,9};
System.out.print(""+array);//<-- print [I#15db9742 or similar
EDIT 2
Encoding the array on the sender side
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
String param = Arrays.toString(array);
param = param.substring(1, param.length()-1);//removing enclosing []
String encArray = URLEncoder.encode(param, "utf-8");
// Send encArray as parameter.
resp.sendRedirect(("result.jsp?fibSequence=" + encArray));
Decoding the array on the receiver side
String encArray = request.getParameterValues("fibSequence");
String decArray = URLDecoder.decode(encArray,"utf-8");
//Now you can parse the list into an Integer list
String [] var_array = decArray.split(",");
In jsp, put the code between <% ... %>. If you get some unresolved symbol errors you have to import the missing libraries.
Can be one or more of the following, simply copy the statements at the top of the page.
<%# page import="java.io.*" %>
<%# page import="java.net.*" %>
<%# page import="java.util.*" %>
(maybe java.util is imported per default, I am not sure)
BUT ATTENTION
Be aware of not sending too much data in this manner! The size of an URL maybe is not unlimited. Also the data is visible in the URL, a 'nasty' user could simply copy and reproduce requests.
A better way to send data is using HTTP post.
Here is the better answer to transfer array variable from servlet to jsp page:
In Servelet:
String arr[] = {"array1","array2"};
request.setAttribute("arr",arr);
RequestDispatcher dispatcher = request.getRequestDispatcher("yourpage.jsp");
dispatcher.forward(request,response);
In Jsp:
<% String str[] = (String[]) request.getAttribute("arr"); %>
<%= str[0]+""+str[1] %>

How to reload a JSP with request.getAttribute values

I have this application where i want to populate a text file on the basis of entries entered from user interface.
I chose Struts1 for this and i have been able to complete most of the functionalities.But the part of keeping on populating the
text file on the basis of user entries in my JSP is something i am struggling with. The following are the flow of pages on user interface
1.'Accept user entries' http://www.image-share.com/ijpg-1178-104.html
2.'Ask for scan data on the basis of entries in page1' http://www.image-share.com/ijpg-1178-105.html
3.'Submit after entering the scandata. ' http://www.image-share.com/ijpg-1178-106.html
(I have been able to straighten the null values in the images via session variables. Thanks to Dave)
message is seen with null entries like this Post validation.
My questions is:
What should be used so that there is a scenario that the users enter the Scan Data on page 2 and can continue to enter
more scan data values by falling back on the same JSP . I was thinking on the lines of reloading the page using JavaScript
on the button click. Is it the right approach?
The relevant code for this is
<html:form action="txtwriter">
<% String itemname = (String)session.getAttribute("itemname"); %>
<% String lotnumber = (String)session.getAttribute("lotnumber"); %>
<% String godownname = (String)session.getAttribute("godownname"); %>
<br/>
<% String message = (String)session.getAttribute("message");
session.setAttribute( "theFileName", message ); %>
Filename : <%= message %>
<br/> Item Name :<%= itemname %>
<br/> Lot Number :<%= lotnumber %>
<br/> Godown Name :<%= godownname %>
<br/> <bean:message key="label.scandata"/>
<html:text property="scanData" ></html:text>
<html:errors property="scanData"/>
<br/>
<html:submit/>
/* How should the submit button handle the onClick event so that when the users click
after entering the text.
1. The entered text must be populated in the text file using a different action class. (I have this part working)
2.They must be on the same jsp with the scanData text box cleared waiting for the next user entry into that text
box so that this subsequest entry can also be entered into the text file.
Is there a way i can empty the 'scanData' textbox by accessing it by name inside my action so that i can empty it from my action class?
(I am looking for this answer)
*/
I used this inside the LoginAction.java
HttpSession session = request.getSession();
session.setAttribute("message", textFile);
session.setAttribute("itemname",loginForm.getItemName().trim());
session.setAttribute("lotnumber",loginForm.getLotNumber().trim());
session.setAttribute("godownname",loginForm.getStockGodown().trim());
(Not an answer; refactored but untested code for others trying to help.)
This is a refactored action, making it easier to see what's actually going on; the original code is difficult to reason about. The trim() functionality is moved to action form setters to avoid redundancy.
public class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginForm loginForm = (LoginForm) form;
if (invalidForm(loginForm)) {
return mapping.findForward("failure");
}
String fileName = createFile(loginForm);
request.setAttribute("message", fileName);
request.setAttribute("itemname", loginForm.getItemName());
request.setAttribute("lotnumber", loginForm.getLotNumber());
request.setAttribute("godownname", loginForm.getStockGodown());
return mapping.findForward("success");
}
private String createFile(LoginForm loginForm) throws IOException {
ServletContext context = getServlet().getServletContext();
String driveName = context.getInitParameter("drive").trim();
String folderName = context.getInitParameter("foldername").trim();
String pathName = driveName + ":/" + folderName;
new File(pathName).mkdirs();
String fileNamePath = pathName + createFileName(loginForm);
ensureFileExists(fileNamePath);
return fileNamePath;
}
private void ensureFileExists(String fileNamePath) throws IOException {
boolean fileExists = new File(fileNamePath).exists();
if (!fileExists) {
File file = new File(fileNamePath);
file.createNewFile();
}
}
private boolean invalidForm(LoginForm loginForm) {
return loginForm.getItemName().equals("")
|| loginForm.getLotNumber().equals("")
|| loginForm.getStockGodown().equals("");
}
private String createFileName(LoginForm loginForm) {
return loginForm.getItemName() + "_"
+ loginForm.getLotNumber() + "_"
+ loginForm.getStockGodown() + "_"
+ createFileNameTimeStamp() + ".txt";
}
private String createFileNameTimeStamp() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd G 'at' hh.mm.ss z");
String dateTime = sdf.format(Calendar.getInstance().getTime());
String[] tempDateStore = dateTime.split("AD at");
return tempDateStore[0].trim() + "_" + tempDateStore[1].trim();
}
}

How do I send data from Struts action to javascript?

I'm trying to create a webb application using Struts 2 and javascript and I'm having some trouble passing data from my action into my javascript.
This is the list I'm trying to send/access:
List<MarkerClass> markers;
MarkerClass is defined acoprding to belove:
final class MarkerClass
{
public Integer objectId;
public String street;
public String streetNumber;
public String zip;
public String city;
public Integer statusId;
public Float lattitude;
public Float longitude;
}
The action also includes a getter for markers:
public List<MarkerClass> getMarkers()
{
return markers;
}
In my jsp-file I have tried doing this:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function initialize()
{
var titel = "";
for(var i, "${markers}")
{
titel = titel+ "${markers[i].street}";
}
}
The browser substitutes "${markers}" with "[se.fubar.test.MarkerClass#37a4, se.fubar.test.MarkerClass#9ad97c]"
I'm guessing there is a better and smarter way to do this but since I'm a bit new to Struts and is trying to code while under the influence of a migrane the answer elludes me.
You cannot just use a struts variable in a javascript function and expect it to work. Remember that the ${...} stuff gets processed before the HTML for the page is sent to the browser. By the time the javascript is rendered at the browser, you are only left with the textual representations. What you will need to do is something like (check the syntax, I haven't used this stuff i a while):
function initialize() {
var title = "";
<c:foreach var="marker" list="${markers}">
title = title + "${marker.street}";
</c:foreach>
}
Something along those lines anyway... Basically the Javascript seen by your browser will look like
function initialize() {
var title = "";
title = title + "Street1";
title = title + "Street2";
title = title + "Street3";
title = title + "Street4";
}
I hope that makes sense and is related to what you were asking.
By the way, there are usually better ways of accomplishing this functionality that building dynamic js etc. Probably there are built in Struts 2 components that you can use?
you would have to set that variable in request or in session and then access it using a <c:out jsp tag like so
var myVar= '<c:out value="${requestScope.myVar}"/>';
then use the var inside your js.
In case you set an object in request or session you have to use the get method to access the value of an attribute then use it like so:
var myVar= '<c:out value="${requestScope.myObj.attribute}"/>';
(assuming you getter method is getAttribute)
it is not possible to access data in session or request directly from js
hope this helps
You could convert the object to json on the server (see http://www.json.org/java/index.html ) and then call eval() on the string to get a javascript representation of your object.
you can try accessing it something like this.
but you have to use a loop to fetch each object from the list place it on the value stack and than fetch each object of it.else you can ask ognl to do it for you.something like
<script type="text/javascript">
function initialize()
{
var titel = "";
for(var i, "${markers}")
{
titel = titel+ <s:property value="%{markers.get(i).street}">;
}
}
just try it since OGNL has capacity to access the object on the value stack

Categories

Resources