For example i have java class post:
public class Post{
String title;
String text;
}
If i create an instance of this class and convert it into ajax response in my servlet controller
#RestController
public class AjaxNewsController {
#JsonView(Views.Public.class)
#PostMapping(value = "/getPost")
public AjaxResponseBody getSearchResultViaAjax(#RequestBody AjaxPostResponse postId) {
AjaxResponseBody result = new AjaxResponseBody();
result.setCode("200");
result.setMsg("found POST");
result.setResult(post);
return result;
}
}
My question is: can i retrieve post fields title and text with javascript on a client side and if i can then how?
Here is an example of console with my response in browse
console
but how can i extract my post with fields in ajax and jquery?
UPD
after some reaserach i found that somehow my serlvet doesn't convert my java pojo into json. How should i do it?
UPD2
my request sends normaly but serlvet doesn't convert POST class into json.
here is my javascript :
function likePost(postId,ratingElem, ratingChange) {
var search = {}
search["postId"] = postId;
search["rating"] = ratingChange;
$.ajax({
type : "POST",
contentType : 'application/json; charset=utf-8',
dataType : 'json',
url : "likePost",
data : JSON.stringify(search),
timeout : 100000,
success : function(data) {
console.log("SUCCESS: ", data);
changeRating(ratingElem,data.post.getTopic());
},
error : function(e) {
console.log("ERROR: ", e);
changeRating(ratingElem,'error');
},
done : function(e) {
console.log("DONE");
enableSearchButton(true);
}
});
}
status and message is fine but result is empty.
try it:
var req = new XMLHttpRequest();
req.open('POST', 'your_url', false);
req.send(null);
if(req.status == 200)
dump(req.responseText);
and if you want to get data from another domain please read cors
So i solved my problem. I use com.fasterxml.jackson.core so i just need to mark fields in my class that i want to convert into json with #JsonView annotation like
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "post_id",
unique = true, nullable = false)
#JsonView(Views.Public.class)
private Integer postId;
Everything that marked will be converted.
Related
I created a custom tool in AEM and I wanted the custom tool to call a servlet(POST json).
The servlet was called but, request.getParameterMap() return empty map.
My servlet code is
#Component(
service=Servlet.class,
property={
Constants.SERVICE_DESCRIPTION + "=Custom Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.paths=" + "/apps/myapp/customServlet"
}
)
public class CustomServlet extends SlingAllMethodsServlet{
#Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
String method = request.getMethod(); // method POST OK
Map map = request.getParameterMap(); // return map but empty
String name = request.getParameter("foo"); // also this return null
response.setStatus(SlingHttpServletResponse.SC_OK);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().print("{\"response message\" : \"" + foo + "\"}");
}
}
and my JS code(loaded to AEM custom tool page as a client library)
window.onload = function() {
var url = '/apps/myapp/customServlet';
var button = document.getElementById('btnSubmit');
button.addEventListener('click', event => {
var foo = document.getElementById('foo').value;
if (foo.length < 1){
alert("input required!!");
} else {
var requestData = {};
requestData.foo= foo;
console.log(requestData); // it is ok
postData(url,requestData).then(data => {console.log(data);}); // got {response message:null}
}
});
}
async function postData(url, data){
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
return response.json();
}
In addition, I deleted POST at filter methods in Adobe Granite CSRF Filter Config.
Do I need any other OSGi config or something wrong with my code to use Post Servlet in AEM?
To get payload from request body, you can use request.getReader()
For example:
String body = IOUtils.toString(request.getReader()); //apache commons io
Or use some json mapper to immediately get your java object
YourObject yourObject = new ObjectMapper().readValue(request.getReader(), YourObject.class); // jackson
I'm seeing
var requestData = {}; // creating an empty array
and you are posting this to the servlet.
I think you want to parse 'foo' from document.getElementById to the servlet.
I am trying to verify username and other fields while creating a change password page.The problem is AJAX call in Jquery script is not hitting my controller.i tried giving hard coded path also in url field of the ajax request.
Below is my Script
this checkUname function is triggering on onblur event from one of the input field.
<script type="text/javascript">
function checkUname()
{
// get the form values
var uName = $('#username').val();
var secQues = $('#secQues').val();
var secAns = $('#secAns').val();
var dataObject = JSON.stringify({
'uName' : uName,
'secQues': secQues,
'secAns' : secAns
});
$.ajax({
url:"validateCredentials.do" ,
type: "POST" ,
data: dataObject ,
contentType: "application/json; charset=utf-8" ,
dataType : 'json' ,
success: function(response)
{
alert(response);
} ,
error: function()
{
alert('Error fetching record.... Sorry..');
}
});
}
</script>
This is my MVC controller
#Controller
public class ArsController
{
#RequestMapping(value="validateCredentials.do", method = RequestMethod.POST)
public String changePass(#RequestParam("uName") String uName ,#RequestParam("secQues")String secQues,
#RequestParam("secAns") String secAns)
{
System.out.println("AJAX request");
Users dummyUSer = null;
String msg = null;
try
{
dummyUSer = servObj.findUser(uName);
}
catch (ArsException e)
{
System.out.println("error occurred while validating user data during password change");
e.printStackTrace();
}
if(dummyUSer == null)
{
msg = "No user exists with this username";
}
else
{
if(!secQues.equals(dummyUSer.getSecQues()))
{
msg = "Security question is not correct";
}
else
{
if(!secAns.equals(dummyUSer.getSecAns()))
{
msg = "Security answer does not match";
}
}
}
return msg;
}
Instead of using RequestParam in controller, you should use String. Because when we are posting JSON data it will not come as individual parameters in Request, instead it will be received as String in your controller. Once you get the String convert it to JSON object and then get your values accordingly.
try remove content-type and data-type.
You are not sending a json that should be parsed in a object, you are sending controller's parameters.
The way to do that is using an object in the Ajax 's data (as you did) but without the content-type or data-type that saying "I'm sending one json parameter"
I'm trying to call a controller method that will save my object, but when i try to url to it, it returns http error. I've browsed through some similar problems on SO but no luck. So i wanna ask myself...
Here is my Ajax (for simplicity purposes i renamed the variables):
function addDob() {
var var1 = $("#var1").val();
var var2 = $("#var1").val();
var var3 = {};
var3["var3"] = $("#var3").val();
var json = JSON.stringify({
var1 : var1,
var2 : var2,
var3 : var3
});
console.log(json);
alert(json);
$.ajax({
url: 'add_dob',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: json,
success: function (data) {
console.log(json);
alert(data.message);
resetForm();
},
error: function () {
alert("Error!");
}
});
}
Here is my controller:
#RequestMapping(value = "/add_dob", method = RequestMethod.POST, produces = "application/json")
#ResponseBody
public Map<String, Object> saveDob(#RequestBody DobavljacWrapper wrapper) {
Map<String, Object> data = new HashMap<>();
Dob d = new Dob();
d.setCountryID(wrapper.getCountryID());
d.setDobName(wrapper.getDobName());
d.setYear(wrapper.getYear());
dobService.save(d);
data.put("message", "Dob was successfully saved!");
return data;
}
Any suggestion is welcomed. If i need to insert any more info, just let me know. Cheers! P.S. I had a similar project that works, but my model classes were different, so i suspect there's something to it..
UPDATE 1.0:
I figured out it has a lot to do with the #RequestBody parameter.
That parameter matches the one you are pushing through with your Ajax. Now, I need that parameter to match my object which has the exact attributes I am passing through with Ajax. Somewhere in there i am making a mistake, and i'm not sure what exactly is the right way here...
If i set "#RequestBody String someString" it will return the parameters i pushed with ajax, but i won't be able to access that info with the getters 'cause it's a string. So i need an object to collect those values!
The answer was the Wrapper class.
It couldn't assign values to it and threw error because i set attributes to "private".
Setting them "public" solved it for me.
Can't believe that was the error...
I have a C# method that works if you call it from another C# method, but not from javascript. How do I make it work from my ajax call?
I need to get a file based on an ID that is passed in, so I have an ajax post with the statusID. That ID is pulling the proper file in my C# method, it is just not giving the file save dialog.
However, if I call this from my C# page load method with a static statusID for testing purposes, it works just fine.
Here is the C# method:
public void Get_Attachment_By_StatusID(int statusID)
{
SqlDataReader _reader = null;
string _connString = "Data Source=133.31.32.33;Initial Catalog=Reports;Integrated Security=True";
string sql = "SELECT a.StatusID ,a.DocumentName ,a.MIMETypeID ,a.Binary ,a.CreatedDate ,a.CreatedBy " +
",b.MIMEType FROM Attachments a Inner join MIME_Types b on a.MIMETypeID = b.ID " +
"WHERE [StatusID] = {0} ";
sql = string.Format(sql, statusID);
try
{
_connection = new SqlConnection(_connString);
_connection.Open();
using (SqlCommand cmd = new SqlCommand(sql, _connection))
{
cmd.CommandType = System.Data.CommandType.Text;
_reader = cmd.ExecuteReader();
if (_reader.HasRows)
{
while (_reader.Read())
{
System.Web.HttpContext.Current.Response.ClearContent();
System.Web.HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
System.Web.HttpContext.Current.Response.ContentType = _reader["MIMEType"].ToString();
System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + _reader["DocumentName"].ToString() + ";");
byte[] b = (byte[])_reader["Binary"];
System.Web.HttpContext.Current.Response.BinaryWrite(b);
System.Web.HttpContext.Current.Response.Flush();
System.Web.HttpContext.Current.Response.Close();
}
}
_reader.Close();
_connection.Close();
}
}
catch (Exception ex)
{
//Log exception to error Logging app
string err = ex.ToString();
}
finally
{
if (_connection != null)
_connection.Close();
if (_reader != null)
_reader.Close();
}
}
Here is how I am calling it from my page, in javascript:
function GetFile(statusID) {
var url = '/Home/Get_Attachment_By_StatusID';
$.ajax({
url: url,
type: 'post',
cache: false,
data: JSON.stringify({ "statusID": statusID }),
contentType: 'application/json',
success: function (data) {
}
});
}
Nothing happens. In Chrome, I don't see anything in the javascript console, and in IE, my console spits this out: "XML5619: Incorrect document syntax."
Again, if I go into the controller, and call the method in my page load method, it presents the save file dialog and saves the file just fine. So I must be doing something wrong with my javascript/jquery/ajax...
I am new to MVC4 and know I'm missing something here. What am I missing?
Use window.open('CONTROLLER_URL/STATUS_ID'); instead of an AJAX request.
<a target="_blank" href="javascript:window.open('/Home/Get_Attachment_By_StatusID/12345');">Test</a>
Here's one suggestion, largely based on answer from LastCoder:
Decorate your action with the [HttpGet] attribute and change the parameter name to id:
[HttpGet]
public void Get_Attachment_By_StatusID(int id) ...
Now in your client-side code, simply do this:
function GetFile(statusID) {
var url = '/Home/Get_Attachment_By_StatusID/'+statusID;
window.location=url;
}
Im constructing an array of objects like this:
var postData = [];
$.each(selectedFields, function (index, value) {
var testTitle = 'testing ' + index;
postData.push({title: testTitle, title2 : testTitle});
}
I then post it like this(note that i have tried a number of different aproaches):
$.post('SaveTitlesHandler.ashx', { form : postData }, function (data) {
console.log(data);
});
I then try to get the data in a handler...
public class SaveTitlesHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string json = context.Request.Form.ToString();
}
}
I cant seem to get proper json out of the request. Anyone got any idea?
cheers.
twD
You are not posting JSON. You are using application/x-www-form-urlencoded. So inside the handler you could access individual values:
public void ProcessRequest(HttpContext context)
{
var title1 = context.Request["form[0][title]"];
var title2 = context.Request["form[0][title2]"];
var title3 = context.Request["form[1][title]"];
var title4 = context.Request["form[1][title2]"];
...
}
If you wanted to POST real JSON you need this:
$.ajax({
url: 'SaveTitlesHandler.ashx',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(postData),
success: function(result) {
console.log(result);
}
});
and then inside the handler read from the request input stream:
public void ProcessRequest(HttpContext context)
{
using (var reader = new StreamReader(context.Request.InputStream))
{
string json = reader.ReadToEnd();
}
}
The JSON.stringify method converts a javascript object into a JSON string and it is a native method built-in modern browsers. You might also need to include json2.js if you want to support older browsers.