Spring mapping effected by #ResponseBody - ajax

I am making an ajax call to my Spring controller to get data from a blob object. I convert the blob to String, and try to return it. If I don't use #ResponseBody annotation, I get a 404 error, but using the annotation solves this.I tried specifying different datatypes in the ajax code, but it has no effect.
Can somebody please explain this behaviour to me. Also any suggestions regarding passing blob data back, in a better way ?
#RequestMapping(value = "/BlobData", method = RequestMethod.GET)
public #ResponseBody String genBlobData(int Id) throws SQLException {
Blob blob = daoImpl.getBlob(Id);
byte[] content = blob.getBytes(1, (int) blob.length());
String temp = new String(content);
return temp;
}
And the ajax :
$.ajax({
type: 'GET',
dataType: "text",
url: 'BlobData',
data: {Id:Id},
success: function(data)
{
var newWindow = window.open();newWindow.document.write(data);
/* alert(data); */
}
});
Thanks

Without #ResponseBody, the returned string is expected to be a relative path to your view (e.g. JSP file), hence the 404.
See http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-viewresolver-resolver.

Related

How to receive multiple Data in controller side using FormData(Ajax)?

My ajax has used FormData and append multiple Field value (like Text-box,label,File) in single(FormData) object. and i have posted that data at server side but
How to receive same data object in controller?
FormData variable :
var uploadFile = new FormData();
var files = $("#UploadFile").get(0).files;
if (files.length > 0) {
uploadFile.append("Doc", files[0]);
}
FileUpload(uploadFile);
Javasacript method Ajax Call :
function FileUpload(uploadFile)
{
var url = '#Url.Action("UploadCsvFile")';
$.ajax({
url:url,
contentType: false,
processData: false,
data:uploadFile,
type: 'POST',
success: function () {
alert("Successfully Added & processed");
}
});
My Question is....if in case,My ajax has more Data, How to receive the same data in controller side and what, if i want to use specific Data object.
You can receive customized forms that are quite complex
It will work in two parts:
Part 1 - Extending the html FormData:
uploadFile.append("TextData", "This is my text data");
Part 2 - Extending your controller:
I assume your model would look something like this:
public class MyModel
{
public HttpPostedFileBase Doc{ get; set;}
}
Now just add your custom data to it:
public string TextData {get;set;}
And in your controller method:
public JsonResult MyUploadMethod(MyModel model)
{
/*From here you will have access to the file and the text data*/
}
Hope it helps. Ask me any questions if you need help.

How to show model attribute in JSP after using ajax?

I have a problem. I pass index value from JSP to controller successfully with ajax. When I click 'pass' button, the 'index' value is increasing and it passes to controller successfully with ajax. According to this index, I add list[index] to model.(with model.addAttribute) Although I have used ${nextWord} in the JSP, I cannot see this value in the view. How can I fix it? Thanks for your answer.
Controller
private List<Map<String, Object>> list;
#RequestMapping(value="/practice/{category}", method = RequestMethod.GET)
public String practicePageStart(#PathVariable("category") String category,
ModelMap model, HttpSession session){
// return 10 value from DB. Example;
// [{idWord=1},{word='exampleWord'},{meaning='turkishMeaning'},{type='NOUN'}]
list = wordService.getRandomWords(Integer.parseInt(String.valueOf(session.getAttribute("wordCount"))));
model.addAttribute("wordList", list);
return "practiceCategory";
}
#RequestMapping(value="/practice/{category}", method = RequestMethod.POST)
public String practicePagePost(#PathVariable("category") String category,
#RequestParam("index") int index, ModelMap model, HttpSession session){
model.addAttribute("nextWord", list.get(index).get("word"));
return "practiceCategory";
}
JSP
<script>
$(document).ready(function() {
$('#pass').click(function(event) {
var inputIndex = $('#index').val();
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/practice/${category}",
async: false,
data: { index: inputIndex }
complete: function(){
alert("${nextWord}");
$('#label').text("${nextWord}");
}
});
document.getElementById("index").value = (parseInt(document.getElementById("index").value) + 1).toString();
});
});
</script>
Change your controller method to this:
#RequestMapping(value="/practice/{category}", method = RequestMethod.POST)
#ResponseBody
public String practicePagePost(#PathVariable("category") String category,
#RequestParam("index") int index, ModelMap model, HttpSession session){
return list.get(index).get("word");
}
And your ajax to this:
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/practice/${category}",
async: false,
data: { index: inputIndex }
success: function(data){
alert(data);
$('#label').text(data);
}
});
Use #ResponseBody and return the object rather then returning a ViewResolver.
Returning a ViewResolver will resolve the view and send the html content while doing an Ajax call. Hence, it is not recommended if u need only value.
#ResponseBody example
public #ResponseBody Integer retriveValue(-,-,-){
return Integer.valueOf(5);
}
In my opinion you mix different:
(1) rendring phase (servlet container - background - java) vs.
(2) running in browser (js, no request attribute existing here).
You need one another jsp file just for rendering the data. Or you return it as json in practicePagePost method.
#ResponseBody
#RequestMapping(value="/practice/{category}", method = RequestMethod.POST)
public String practicePagePost(#PathVariable("category") String category,
#RequestParam("index") int index, ModelMap model, HttpSession session){
return list.get(index).get("word");
}

Ajax POST call to Spring MVC

This question is follow up of Returning ModelAndView in ajax spring mvc
As the only answer says that we need to return json from Controller not ModelAndView. So the question is
what can be done to return ModelAndView ?
How the page will be rendered:-
will it have to be handled in success section of ajax call
Or Spring Controller will return the page as usually it does in Spring MVC
How the post data from ajax can be read in Controller.
Update 1:
As explained, I tried example. here is my code.
#Controller
public class AppController
{
#RequestMapping(value="/greeting",method=RequestMethod.POST)
#ResponseBody
public ModelAndView getGreeting(#RequestBody String json) throws IOException
{
JSONObject inputjsonObject = new JSONObject(json);
String name = inputjsonObject.getString("name");
ModelAndView modelAndView = new ModelAndView();
String result = "Hi "+name;
modelAndView.addObject("testdata", result);
modelAndView.addObject("user", getPrincipal());
modelAndView.setViewName("greetingHtmlPage");
return modelAndView;
}
// other stuff
}
In above controller method i can get data sucessfully. This method is called from a javascript on home.html. Below is javascript function
function callGreeting(){
var nameData={
name : document.getElementById("name").value
}
var dataInJson = JSON.stringify(nameData);
var csrf_token = document.getElementById("token").value;
$.ajax({
type: 'POST',
url: "greeting",
data: dataInJson,
cache:false,
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json");
},
success: function (response) {
document.open();
document.write(response);
document.close();
},
error: function (data) {
alert("failed response");
}
}); }
I have the page rendered successfully. But the url of application does not changes from AjaxSpringMVC:8080/home to AjaxSpringMVC:8080/greeting even after new page was loaded. This happens by itself in Spring MVC if using without Ajax.
what can be done to return ModelAndView ?
You can return ModelAndView As usual:
public ModelAndView returnView( Model model ) {
model.addAttribute( "myStaff", "my staff as string" );
return new ModelAndView( "myView" );
}
How the page will be rendered:
You control how it is rendered, .
When you return ModelAndView, the response has an HTML page.
After the Ajax call, you can do $("#container").html(response) or something like that to display the HTML page wherever you want.
In other words, you get a whole html page of content from the controller.
However, I highly recommend that you just return json object and update your view with the json object. Ajax is mostly used to create good user experience by updating part of the view asynchronously, so getting a whole page with Ajax does not make sense to me.
How the post data from ajax can be read in Controller.
There are many ways, I like to send json body directly to controller
#ResponseBody
#RequestMapping(value = "/saveObj", method = RequestMethod.POST, consumes = "application/json")
public String saveObj(Model model, #RequestBody MyObj myObj) {
// do staff..
}

How to map Bootstrap Modal to Spring MVC controller

I have a form in Bootstrap Modal and I want my Spring MVC controller to listen that. My problem is that the modal doesn't generate href because it's inside current page so I can't map just the modal in my Spring MVC controller.
I need it, because I want to show errors from bindingresult object. How can I do this?
This is my modal: http://www.bootply.com/zerZIYpNAF Let's say it's located in index.jsp so imaginary path would be /index#myModal.jsp or something like that.
#RequestMapping(value="/send", method = RequestMethod.GET)
public String get(Dummybean bean){
return "??"; //index#myModal
}
#RequestMapping(value="/send", method = RequestMethod.POST)
public String post(#Valid #ModelAttribute("dummy") DummyBean bean, BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "??"; //index#myModal
}
//do something
}
public class DummyBean{
#NotNull
private String name;
public String getName() {
return username;
}
public void setName(String name) {
this.name = name;
}
You can't directly call the bootstrap modal to pop up by using controller. There for you will not able to bind form with Spring. But you can Achieve it using Ajax. You have to use form like normal Html form without using spring tags.
function searchAjax() {
var data = {}
data["query"] = $("#query").val();
$.ajax({
type : "POST",
contentType : "application/json",
url : "${home}search/api/getSearchResult",
data : JSON.stringify(data),
dataType : 'json',
timeout : 100000,
success : function(data) {
console.log("SUCCESS: ", data);
display(data);
},
error : function(e) {
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
console.log("DONE");
}
});
}
This is an example ajax for you to get an idea. You have to HttpServletRequest to retrieve data from controller side. Above example is taken from http://www.mkyong.com/spring-mvc/spring-4-mvc-ajax-hello-world-example/
1) create new function just for validation
2) create js function using prefer to use jquery and send ajax request to function in step one.
3) depend on validation status will handle errors or send form completely.
please read this article it's fully answered your question
javacodegeeks.com

How to Post the Form values to the Controller in Mvc without Model and uSing Ajax?

I need to post the from Property name and values to the Mvc web api Controller without using model Property because i need to use same Ajax call (method) for different Forms also.
Using this Ajax Method i need to Post values i am Posting values but how i need to receive those values in Controller
Example Of Posting:
function Add(){var model = $("#Enquiry").serialize();
$.ajax({
url: 'http://localhost:60533/api/Enquiry',
type: 'POST',
dataType: 'json',
data: model,
success: function (data) {
console.log(data);
}
});}
Using Below Controller how can i Receive model Values without using C# (Get set Property) Model?
public HttpResponseMessage Post(object model)
{
var Result = (new EnquiryDtl().Post(model));
return Request.CreateResponse(HttpStatusCode.OK);
}
This is how I do it...
var dataArray = $("#Enquiry").serializeArray(),
var model = {};
for (i = 0; i < dataArray.length; i++)
model[dataArray[i].name] = dataArray[i].value;
var url = 'http://localhost:60533/api/Enquiry';
$.ajax({
url: url, type: "POST", dataType: 'json',
data: JSON.stringify(model), contentType: 'application/json',
success: function (data) {
....
}
});
and in the controller:
public HttpResponseMessage Post(Dictionary<string, string> fields)
{
...
}
As you've undoubtedly discovered, object doesn't have a lot of useful properties on it. This is where using a model really comes in handy. For example, let's say you're posting an integer called ID and a string called Name, then this simple object would be populated accordingly:
public class MyModel
{
public int ID { get; set; }
public string Name { get; set; }
}
And you'd use it in your method:
public HttpResponseMessage Post(MyModel model)
{
// here you can access model.ID and model.Name
}
If you really don't want to use a model, you can include the values directly in the method signature:
public HttpResponseMessage Post(int id, string name)
{
// here you can access id and name
}
Of course, using a model brings a lot more advantages. Specifically, you can add business logic to the model (since business logic belongs on the models and not on the controllers). Additional benefits include being able to modify the structure without having to modify all consuming code. (For example, if you have multiple methods which accept this structure then you'd have to change all of them to add a new field. With a model, you'd only have to change that one model.)
Finally I got the Solution To send the Key Pair values to the Mvc Controller using Ajax and web Api.
Without using C# Model get set property
My Script:
function Enquiry() {
var dataArray = $("#formMember").serializeArray(),
model = {};
for (i = 0; i < dataArray.length; i++) {
var Name = "["+i+"]"+""+"."+"Key";
var Value = "[" + i + "]" + "" + "." + "Value"
model[Name] = dataArray[i].name;
model[Value] = dataArray[i].value;
}
$.ajax({
url: 'http://localhost:60533/api/Enquiry',
type: 'POST',
data: model,
success: function (data) {
alert(data);
}
});}
C# Code
I am reciving Those values Instead of Object I am Using Dictionary
public HttpResponseMessage Post(Dictionary<string, string> dictionary)
{
var Result = (new EnquiryDtl().Post(dictionary));
return Request.CreateResponse(HttpStatusCode.OK);
}

Resources