I have a html page and a java application with Thymeleaf templating engine and I'm looking for a tutorial to make a request to the server and render only part of the page based on response.
At this moment, I have some buttons having a link of the same page with a different parameter, my div is created based on attribute articleList (which I receive from the server based on button_id)
HTML:
button 1
button 2
<div class="" th:each="article : ${articleList}">
<p th:text="${article.getText()}">Article</p>
Java:
public class NodController implements IGTVGController {
public void process(
final HttpServletRequest request, final HttpServletResponse response,
final ServletContext servletContext, final TemplateEngine templateEngine)
throws Exception {
final WebContext ctx = new WebContext(request, response, servletContext, request.getLocale());
Integer button_id = Integer.valueOf(request.getParameter("button_id"));
List<String> articleList = getArticleList(button_id);
request.getSession().setAttribute("articleList",articleList);
templateEngine.process("/index", ctx, response.getWriter());
}
I want my buttons to process my index controller and only change the div with the articles and not refresh the entire page.
I have tried using ajax but I didn't find code examples for server-side that I could understand, so I don't know how to process the request and I don't know how to use servlets. Also I didn't manage to send any request to my current controller.
I have also found in thymeleaf api this method:
public final void process(String templateName, IContext context,
IFragmentSpec fragmentSpec, Writer writer)
where IFragmentSpec should "select a fragment of a template to be processed (once read and parsed), discarding the rest of the template" but I couldn't find more information about it as how to use it or if it is what I'm looking for.
this is the javascript code
//get text 1 by ajax
function getText1(urlstarted) {
xmlHttp = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
xmlHttp = new XMLHttpRequest();
if (xmlHttp.overrideMimeType) {
// set type accordingly to anticipated content type
//http_request.overrideMimeType('text/xml');
xmlHttp.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!xmlHttp) {
alert('Cannot create XMLHTTP instance');
return false;
}
var url=urlstarted+"/jsp/viewText1.jsp"; //put the link to ur Ajax page here
xmlHttp.onreadystatechange = startAjaxingText;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function startAjaxingText() {
if (xmlHttp.readyState != 4) {
document.getElementById('image').style.display='block' ;
document.getElementById('result').style.display='none' ;
}
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
document.getElementById('image').style.display='none' ;
document.getElementById('result').style.display='block';
document.getElementById('result').innerHTML = xmlHttp.responseText;
} else {
alert("There was a problem with the request.");
}
}
}
//get text 2 by ajax
function getText2(urlstarted) {
xmlHttp = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
xmlHttp = new XMLHttpRequest();
if (xmlHttp.overrideMimeType) {
// set type accordingly to anticipated content type
//http_request.overrideMimeType('text/xml');
xmlHttp.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!xmlHttp) {
alert('Cannot create XMLHTTP instance');
return false;
}
var url=urlstarted+"/jsp/viewText2.jsp"; //put the link to ur Ajax page here
xmlHttp.onreadystatechange = startAjaxingText2;
xmlHttp.open("GET", url, true);
xmlHttp.send(null);
}
function startAjaxingText2() {
if (xmlHttp.readyState != 4) {
document.getElementById('image').style.display='block' ;
document.getElementById('result').style.display='none' ;
}
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
document.getElementById('image').style.display='none' ;
document.getElementById('result').style.display='block';
document.getElementById('result').innerHTML = xmlHttp.responseText;
} else {
alert("There was a problem with the request.");
}
}
}
now your buttons will look like this
<input name="button_1" id="button_1" type="button" value="button_1" onclick="getText1('<%=request.getContextPath()%>');" />
<input name="button_2" id="button_2" type="button" value="button_2"
onclick="getText2('<%=request.getContextPath()%>');" />
your div will look like
<div id="image" style="display:none"><img src="<%= request.getContextPath()%>/images/ajax-loader.gif" alt="Loading...."/> </div>
<div id="result" style="display:none"></div></td>
your viewText1.jsp page that doing ajax part
out.println("text1");//or any logic u want
your viewText2.jsp page that doing ajax part
out.println("text2");//or any logic u want
note that : the result of viewText1.jsp or viewText2.jsp must be a text either a table or paragraphs
Client-side implementation
You will have to use AJAX to load content from the server dynamically.
Consider designing your frontend as SPA. Look into AngularJS or Knockout.
Also, you can use old-school approach by using something like jQuery AJAX if this is just a small area of your application.
Separation of concerns
I strongly suggest to consider the idea to separate concerns by using server as a REST service and frontend as a client. This is the best practice for large applications if you want to keep them maintainable and scalable.
You should look for tutorials of how to implement REST with your server-side technology. It's very common practice so I think you should be able to find one.
If you have any questions I will be glad to update this answer.
Related
I am busy quite with my new project where I working on jPlayer, completely based on jQuery.
I am very new in jQuery so I am facing lots of problems but now I am little comfortable with jQuery.
My requirement is to access a absolute url if the given url is relative, for that I used some java code. Each and every thing is working well but to fetch the absolute url I used java code for that I used jsp page and execute that using ajax call. Problem is the value returning from jsp is having lots of extra datas, generally all the html tags. I saw this question is already asked by some person and the reply
"use servlet instead of jsp because jsp for presentation and this will output some html".
and my codes are:
function funAJAX(songURL){
var path=document.getElementById("url").value,
ext=songURL.split('.').pop(), // trying to pull extension of link
xmlhttp, absUrl;
//alert(path);
if(window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// code for IE6, IE5
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
//$("#tempUrl").html(xmlhttp.responseText);
//storing val in div of id="tempUrl"
// absUrl=$("#tempUrl").find("info").text();
//fetching the link only
var v=xmlhttp.responseText;
alert("value from ajax: " + v);
if(ext == "mp3" || ext == "Mp3") { // if absolute url then songUrl val will not change
// alert("extension: "+ext);
ext=ext;
}
else { // if relative link then storing the val returned from ajax as absolute link
// alert("in else part");
songURL=absUrl;
}
alert("i2: song url: " + songURL); // this will execute after returning val from jsp because of ajax call
}
};
// alert("2: song url: "+songURL); //this will execute before sending req to jsp page
xmlhttp.open("GET", "" + path + "/html/player/songURLManipulation.jsp?songURL=" + songURL, true); //calling songURLManipulation.jsp with argument songUrl
xmlhttp.send(); //sending the req
}
above is my jsp page and having lots of tag
"/>
this liferay problems but main thing is to implement jplayer
and my another jsp that one I am calling through ajax is
<%
String songURL=request.getParameter("songURL");
String location=null;
if(songURL!=null) {
HttpURLConnection con = (HttpURLConnection)(new URL(songURL).openConnection());
con.setInstanceFollowRedirects( false );
con.connect();
location = con.getHeaderField("Location");
response.getWriter().print(location);
out1.print(location);
}
//return location;
System.out.println("from song manipulation.jsp: "+songURL);
%>
I achieved this one by using serveResource method and calling that method by ajax by using json object but my question is, is it really not achievable through jsp page return value if I call through above describe way.
It is really good to be part of this forum.
my ajax code
function funAJAXServlet(songURL,servletURL)
{
alert("from ajax fun");
jQuery.ajax({
url :servletURL,
data: {"songURL":songURL},
type: "GET",
dataType: "json", //describe the type of value returned from serveResource class
success: function(data) {
//to put data data into div part of html and data is coming from serveResource class.
var jsonobj=data.songUrlServlet;
alert("from servlet ajax: "+jsonobj);
}
});
}
and my serveResource method
public void serveResource(ResourceRequest request, ResourceResponse response)
{
String songURL=request.getParameter("songURL");
JSONObject jsobj=null;
String location=null;
HttpURLConnection con;
System.out.println("songURL from serveResourceUrl servlet method: "+songURL);
if(songURL!=null)
{
try
{
con = (HttpURLConnection)(new URL(songURL).openConnection());
con.setInstanceFollowRedirects( false );
con.connect();
location = con.getHeaderField("Location");
System.out.println("$$$$$$$$$$$4 location val: "+location);
jsobj = JSONFactoryUtil.getJSONFactory().createJSONObject();
if(location!=null)
jsobj.put("songUrlServlet",location);
else
jsobj.put("songUrlServlet","null");
PrintWriter writer = response.getWriter(); //writing to the client page
writer.write(jsobj.toString());
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
//return location;
else
System.out.println("from song serveResource method: "+songURL);
}
This is working fine.
I am creating a web application in java. On client side I have a bar chart that display some data stored in a tsv file created by the java server page. By clicking on a button the server updates these data in the file. Now I want to read the refreshed data, but I get the older ones. It seems that the browser cached the file so it can't get the changed file.
This is my servlet code:
public class GetDataServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
private User user;
Utility utility;
public void init() throws ServletException {
reset();
}
public void doGet (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
PrintWriter out = response.getWriter();
user.getProfile().get(0).setWeigth(user.getProfile().get(0).getWeigth()+0.03);
user.getProfile().get(1).setWeigth(user.getProfile().get(1).getWeigth()+0.02);
user.getProfile().get(5).setWeigth(user.getProfile().get(5).getWeigth()+0.01);
utility.createTsvFile(user, "/usr/local/apache-tomcat-7.0.50/webapps/Visualizer/data.tsv");
String message = String.format("data.tsv");
i++;
out.print(message);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getParameter("reset").compareTo("yes")==0)
reset();
}
private void reset(){
List<Concept> children = new ArrayList<Concept>();
Concept food = new Concept();
food.setWeigth(0.10);
food.setLabel("food");
food.setColor("#98abc5");
Concept dish = new Concept();
dish.setWeigth(0.08);
dish.setLabel("dish");
dish.setParent(food);
dish.setColor("#8a89a6");
Concept cuisine = new Concept();
cuisine.setWeigth(0.06);
cuisine.setLabel("cuisine");
cuisine.setParent(food);
cuisine.setColor("#8a89a6");
children.add(dish);
children.add(cuisine);
food.setChildren(children);
children.clear();
Concept pizza = new Concept();
pizza.setWeigth(0.05);
pizza.setLabel("pizza");
pizza.setParent(dish);
pizza.setColor("#6b486b");
Concept spaghetti = new Concept();
spaghetti.setWeigth(0.05);
spaghetti.setLabel("spaghetti");
spaghetti.setParent(dish);
spaghetti.setColor("#6b486b");
Concept sushi = new Concept();
sushi.setWeigth(0.06);
sushi.setLabel("sushi");
sushi.setParent(dish);
sushi.setColor("#6b486b");
children.add(pizza);
children.add(spaghetti);
children.add(sushi);
dish.setChildren(children);
List<Concept> profile = new ArrayList<Concept>();
profile.add(food);
profile.add(dish);
profile.add(cuisine);
profile.add(pizza);
profile.add(spaghetti);
profile.add(sushi);
user = new User("mario", profile);
utility = new Utility("");
}
}
This is the javascript code that calls the servlet:
function ajaxSyncRequest(reqURL) {
//Creating a new XMLHttpRequest object
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest(); //for IE7+, Firefox, Chrome, Opera, Safari
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); //for IE6, IE5
}
//Create a asynchronous GET request
xmlhttp.open("GET", reqURL, false);
xmlhttp.send(null);
//Execution blocked till server send the response
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
document.getElementById("message").innerHTML = xmlhttp.responseText;
update(xmlhttp.responseText);
//alert(xmlhttp.responseText);
} else {
alert('Something is wrong !!');
}
}
}
function update(file){
d3.tsv(file, function(error, data) {
......
In the html page I have also put this:
<meta http-equiv="Cache-control" content="no-cache">
but it doesn't work.
With this code I can display the correct data the first time I call the servlet, than even if the data in the file tsv changes I get the first one.
Which is the best way to read the refreshed data in the file?
Okay I you are facing problem from browser caching problem like this so two hings can be done
1)You can create a filter and instruct in filter not to cache some what like this Prevent user from seeing previously visited secured page after logout
2)Each time you are hitting the url of tsv file add a random variable in end .(This is usually in case of internet exlorer)
I am trying to use Ajax with Spring Portlet 2.5 (I can't upgrade to higher version because I need to run tests on this one - therefore I can't use #ResourceMapping). So this is what I tried
<script type='text/javascript'>
function <portlet:namespace />setCurrentDateTime() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
//now what?
}
};
xhr.open("GET", '${actionURL}', true);
xhr.send();
}
</script>
<table>
<tr>
<td><b>Refresh</b></td>
</tr>
</table>
<br/>
<div id="<portlet:namespace />messageText">${date}</div>
By this code, action on the server side is correctly trigerred but I am not sure how do I refresh the messageText to have there updated value from the server.
This is my server side code
#RequestMapping
public ModelAndView defaultView(RenderRequest request, RenderResponse response) {
String date = (String) request.getPortletSession().getAttribute("date");
if (date == null) {
return new ModelAndView("home");
} else {
Map<String, Object> map = new HashMap<String, Object>();
map.put("date", date);
return new ModelAndView("home", map);
}
}
#RequestMapping(params = "action=getDateTime")
public void handleActionRequest(ActionRequest ar, ActionResponse ar1) {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
ar.getPortletSession().setAttribute("date", sdf.format(new Date()));
}
Updating the contents of the messageText element would require adding the following into the JavaScript where you currently have "now what?":
document.getElementById("<portlet:namespace />messageText").innerHTML = xhr.responseText;
However, the larger problem is that you're attempting to use Ajax in a portlet with a version of Spring that only supports JSR 168 (Portlet Spec 1.0). Resource Requests, which are how Ajax calls are typically handled, were not introduced until JSR 286 (Portlet Spec 2.0).
Updating the JavaScript with my suggested code results in the entire portal page being added as the innerHTML of the messageText element, as the ActionRequest resulted in a full RenderRequest being triggered for the portlet.
I am very new to ajax concept,I want to submit a form without refresh the page
ajax
function ajaxFunction() {
if(xmlhttp) {
var txtname = document.getElementById("txtname");
xmlhttp.open("POST","Listservlet",true);
xmlhttp.onreadystatechange = handleServerResponse;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("txtname=" + txtname.value);
}
}
function handleServerResponse() {
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
document.fname.message.innerHTML=xmlhttp.responseText;
}
else {
alert("Error during AJAX call. Please try again");
}
}
}
JSP
<form name="fname" action="Listservlet" method="post">
<input type="text" name="txtname" id="txtname" />
<input type="button" value="Submit" onclick="ajaxFunction();" />
<div id="message"></div>
</form>
servlet
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
String name = null;
PrintWriter out = response.getWriter();
if(request.getParameter("txtname") != null) {
name = request.getParameter("txtname");
}
else {
name = "";
}
out.println("You have successfully made Ajax Call:" + name);
}
This ajax idea I got from google, bt it is not working,
While clicking on the button,nothing it showing.
Please help me.
replace
document.fname.message.innerHTML=xmlhttp.responseText;
by
document.getElementById("message").innerHTML=xmlhttp.responseText;
General Steps to find out where goes wrong:
use browser debugger to tell if ajax request was successfully sent;
debug your receiving Servlet, to tell if request was actually delivered to your Servlet;
use browser debugger to tell if the response text is desired one;
for your issue I think you need to
change
document.fname.message.innerHTML=xmlhttp.responseText;
to
document.getElementById("message").innerHTML = xmlhttp.responseText;
Also remember Close your ouputstream
I have an Ajax request coming from client side after a key press. The servlet returns a string.
How should I grab this string on the client side? It should be split on "," on the client side and display the list. We are using Velocity for rendering the HTML.
Servlet code:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String acInfo = request.getQueryString();
SomeDAO dao = new SomeDAO();
ArrayList<String> results = dao.acResults(acInfo);
StringBuilder sb = new StringBuilder();
int count = 0;
for (String acResult : results) {
sb.append(acResult);
count++;
if (count == results.size()) {
break;
}
sb.append(',');
}
out.println(sb);
out.close();
}
Dont use "async: false" or it will lose all the AJAX meaning.
Do all the stuff you want in the success method. To split by ',', just use split() and to easily iterate arrays use $.each()
$.ajax({ type: "GET",
url: "/YourServletURL",
success : function(text)
{
var list = text.split(',');
$.each(list, function(index, value) {
alert(index + ': ' + value);
});
// This will show the values. Change "alert" for $('div#mydiv').html(value) or so
}
});
If you are not using Jquery then you can use following:
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","YOUR_SERVLET_RELATIVE_URL",true);
xmlhttp.send();
}
</script>
</head>
<body>
<h2>AJAX</h2>
<button type="button" onclick="loadXMLDoc()">Request data</button>
<div id="myDiv"></div>
</body>
</html>
Sounds like a simple jQuery ajax response scenario - can't you handle the response with code of following nature ?
var responseText = '';
$.ajax({ type: "GET",
url: "/YourServletURL",
success : function(text)
{
responseText = text;
}
});
//alert response or process it or display somewhere
alert(responseText);