How to map JSON object to Spring Object... I have AJAX, posting a JSON object to my Spring Controller but how do I make Spring turn that JSON into a Object in java
Java Code:
#RequestMapping(method=RequestMethod.POST, value="/employee")
public ModelAndView addEmployee(#RequestBody String body) {
System.out.println("in post: " + body);
Source source = new StreamSource(new StringReader(body));
System.out.println("source: " + source.toString());
//
// how do I turn the JSON String into a Java Object?
//
return new ModelAndView(XML_VIEW_NAME, "object", body);
}
JavaSript/html code:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>This is a project to show how to use RESTful</title>
</head>
<body>
<script type="text/javascript">var contexPath = "<%=request.getContextPath()%>";</script>
<script src="<%=request.getContextPath()%>/js/jquery.js"></script>
<script type="text/javascript">
function doAjaxPost() {
var queryString = $('#htmlform').serialize();
alert("doAjaxPost Called :" + queryString +":");
$.ajax({
contentType : "application/json",
dataType : 'json',
type : "POST",
url : contexPath + "/service/employee",
data : queryString, //json serialization (like array.serializeArray() etc)
success : function(data) {
alert("Thanks for submitting. \n\n" + response.result);
// response
},
error : function(request, status, error) {
alert('Error: ' + e);
}
});
}
</script>
<H1>Add Employee</H1>
<p>
<form name="htmlform" id="htmlform">
<table border=1>
<thead><tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
</tr></thead>
<tr>
<td><input type="text" name="ID" maxlength="5" size="3"></td>
<td><input type="text" name="Name" maxlength="10" size="10"></td>
<td><input type="text" name="Email" maxlength="10" size="10"></td>
</tr>
</table>
<input type="button" value="Save Employee" onclick="doAjaxPost();" />
<p>
<p>
</form>
[List all Employees | Employee Form Test]
</body>
</html>
Make sure to:
send JSON object, not JSON String
included Jackson on your classpath
Then you can add #RequestBody Employee employee at the controller's method signature.
I suppose you're using Spring 3.0+. Take a look at Spring Source blog post on JSON simplifications. It seems that you're half way there already.
Use JSON mapping library such as Jackson or Gson
Your code would look approximately as :
Employee e;
try {
e = objectMapper.readValue(body, Employee .class);
} catch (IOException e) {
throw new IllegalArgumentException("Couldn't parse json into a employee", e);
}
If you using Spring 3 or higher, there is even simpler way to do it:
http://blog.springsource.org/2010/01/25/ajax-simplifications-in-spring-3-0/
Related
I would like to display the data I get from a search, personalized for my taste. At this moment, It is just plain text.
For example, I am searching for "Titanic", and I get the name, a few links, and some information from IMDB.
I have the following code:
search.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="#{/search}" th:object="${search}" method="post">
<p>Message: <input type="text" th:field="*{content}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</body>
</html>
result.html
<!DOCTYPE HTML>
<html xmlns:th="https://www.thymeleaf.org">
<head>
<title>Getting Started: Handling Form Submission</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'content: ' + ${main.content}"></p>
Submit another message
</body>
</html>
SearchController.java
#Controller
public class SearchController {
#GetMapping("/search")
public String greetingForm(Model model) {
model.addAttribute("search", new Main());
model.addAttribute("main", new Main().getContent());
return "search";
}
#PostMapping("/search")
public String greetingSubmit(#ModelAttribute Main main) {
return "result";
}
}
and Main.java
private String content;
private List<Result> finalList;
private List<Result> resultList;
public void setContent(String content) throws IOException {
//code to compute finalList
}
public List<Result> getContent() {
return this.finalList;
}
The main problem is that I have no ideea where to being with. finalList is a list of objects of type "Result", which have fields such as
private List<String> link = new ArrayList<>();
private String name;
private TitleProp titleProp;
and TitleProp has
private String trailer;
private String rating;
private String description;
private String genre;
I would like to manipulate each field to show it on a different way, such as a table with more rows, etc.
Any link or sample of code would help me a lot to understand Thymeleaf and Spring Boot more.
I am coming with an answer to my question. I managed to get the result I wanted using Ajax, as SnakeDoc suggested. It was a long road, mostly because even if I had a working code, I spent a few hours searching for the Forbidden 403 error on ajax post request.
So, for the js part:
function ajaxPost() {
// Here we prepare data for the JSON
var formData = {
moviename: $("#moviename").val()
}
$.ajax({
type: "POST",
contentType: "application/json",
url: "MYURL",
data: JSON.stringify(formData),
dataType: 'json',
success: function (result) {
{
$.each(result,
function (i, title) {
// do whatever you want with what you got from the server
});
console.log("Success: ", result);
}
console.log(result);
},
error: function (e) {
console.log("ERROR: ", e);
}
});
}
If this seems confusing, I access the fields you can see in my question by
title.name, title.link, title.titleProp.description, etc, inside function (i, title)'s body.
For the HTML,
<label for="moviename" style="margin-right:5px">Title:</label>
<input type="text" class="form-control" id="moviename" placeholder="Enter a title"/>
Where moviename is the variable name you get from the input.
Now, on the backend, we have to configure our path
#PostMapping("/MYURL")
public ResponseEntity<Object> addSearch(#RequestBody SearchCriteria searchCriteria)
throws IOException {
// do whatever you want to get a result. I used a custom class "SearchCriteria"
// which has a getter and a setter for the field
// **private String moviename;**
return ResponseEntity.ok(THIS GETS SENT TO AJAX);
}
The main problem was that I have web.security, and you have two choices. First one, you disabling csrf. You have to add this line to your security config.
http.csrf().disable();
in protected void configure(HttpSecurity http) method.
Or, you add csrf to the ajax request. More info on this topic was discussed here
With thymeleaf, you can display a list in html like so:
<tr th:each="student: ${students}">
<td th:text="${student.id}" />
<td th:text="${student.name}" />
</tr>
More info: https://www.baeldung.com/thymeleaf-iteration
I have 3 pages, I want to do that when I enter name in textbox. Email and Phone display in different textbox using ajax. It displays both values in 1 textbox but I want both values in two different textboxes.
HTML
This is my html page:
<%--
Document : Test
Created on : Oct 10, 2017, 9:59:46 PM
Author : Lenovo
--%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="Bootstrap/bootstrap.css"/>
<title>JSP Page</title>
</head>
<body>
<form action="NameDB.jsp" method="post" name="add_name" id="add_name">
<table class="table table-bordered" border="1" id="dynamic_field">
<tr>
<th>Enter Name</th>
<th>Enter email</th>
</tr>
<tr>
<td><input type="text" name="name_1" placeholder="Enter Name" size="25" class="searchName" id="search1"/></td>
<td><input type="text" name="email_1" id="esearch1"/></td>
<td><input type="text" name="phone_1" id="psearch1"/></td>
<td>
<button type="button" name="add" id="add">Add More</button>
</td>
</tr>
</table>
<input type="submit" name="submit" value="Submit"/>
</form>
JQuery
This is my Jquery and Ajax
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
$(document).ready(function()
{
var i=1;
$('#add').click(function()
{
i++;
$('#dynamic_field').append('<tr id="row'+i+'"><td><input type="text" id="search'+i+'" class="searchName" name="name_'+i+'" placeholder="Enter Name"/></td>\n\
<td><input type="text" id="esearch'+i+'" class="searchEmail" name="email_'+i+'"/></td>\n\
<td><input type="text" id="psearch'+i+'" class="searchPhone" name="phone_'+i+'" placeholder="Enter Phone"/></td>\n\
<td><button type="button" name="remove" id="'+i+'" class="btn btn-danger btn_remove">X</button></td>\n\
<td><input type="hidden" name="count" value="'+i+'"/></td></tr>');
});
$(document).on('click','.btn_remove',function()
{
var button_id=$(this).attr("id");
$('#row'+button_id+'').remove();
});
$(document).on('change','.searchName',function()
{
var id=$(this).attr("id");
var name=$('#'+id).val();
//var email=$('#e'+id).val();
$.ajax({
url:"AjaxDB.jsp",
type:"post",
dataType:"text",
data:{name:name},
cache:false,
success:function(data)
{
//$('#show').html(data);
$('#e'+id).val(data);
}
});
});
});
AjaxDB.JSP
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#page language="java"%>
<%#page import="java.sql.*"%>
<%#page import="java.util.*"%>
<%
try
{
String name=request.getParameter("name");
String email=null;
String phone=null;
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/atm","root","root");
Statement st=con.createStatement();
ResultSet rs;
rs=st.executeQuery("SELECT * FROM test where name='"+name+"'");
while(rs.next())
{
email=rs.getString("email");
phone=rs.getString("phone");
out.print(email);
out.print(phone);
}
}
catch(Exception e)
{
System.out.println(e);
}
%>
If you want to receive data from server, then it is recommend to use JSON. You are sending data as plain text from "AjaxDB.JSP"
If response is by using JSON, then you should Servlet instead of JSP page.
Both following points are explained through code:
Your servlet code might be following:
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import org.json.simple.*;
public class DemoServlet extends HttpServlet {
public void doGet(HttpServletRequest req,HttpServletResponse res)
throws ServletException,IOException
{
res.setContentType("application/json");//setting the content type
PrintWriter pw=res.getWriter();//get the stream to write the data
JSONObject response = new JSONObject();
try {
String name=request.getParameter("name");
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/atm","root","root");
Statement st=con.createStatement();
ResultSet rs;
rs=st.executeQuery("SELECT * FROM test where name='"+name+"'");
JSONArray list = new JSONArray();
while(rs.next()) {
JSONObject obj = new JSONObject();
obj.put("email",rs.getString("email"));
obj.put("email",rs.getString("phone"));
list.add(obj);
}
response.put("response", list);
} catch(Exception e) {
System.out.println(e);
}
pw.println(response.toJSONString());
pw.close();//closing the stream
}
}
And your client side code can be following:
$.ajax({
url:"AjaxDB.jsp",
type:"post",
dataType:"json",
data:{name:name},
cache:false,
success:function(data) {
console.log(data);
console.log(data.response[0].email);
console.log(data.response[0].phone);
}
});
});
Special Note: The code is untested. So debug if any error found!
I want to edit data of the user by inputting new value in the textbox such as his first name and show these changes in his profile.
I tried to use Ajax but I don't understand what the url should be in there.
That's my jsp file with edit form and Ajax script:
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<script type="text/javascript">
$("edit").click(function() {
var firstName = $(request.getParameter("firstname")).val();
$.ajax({
url: '',
type: 'POST',
data: {
firstName: firstName
}
});
});
</script>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>
<h4>To edit your information fill the fields, please.</h4>
<form name='f' action="${pageContext.request.contextPath}/j_spring_security_check" method='POST'>
<table>
<tr>
<td>First Name:</td>
<td><input type='text' name='firstname' id='firstname' value='${firstname}'></td>
</tr>
<tr>
<td><input name="edit" type="submit" value="Submit" /></td>
</tr>
</table>
</form>
I have update and get methods for the first name in one of the classes:
public class UserInfoDAOImpl extends JdbcDaoSupport implements UserInfoDAO {
#Autowired
public UserInfoDAOImpl(DataSource dataSource) {
this.setDataSource(dataSource);
}
//.....other methods
#Override
public void editFirstName(String userName, String fName){
String sql = "update Users set FirstName = ? where Username = ?";
Object[] params = new Object[] {fName, userName};
this.getJdbcTemplate().update(sql, params);
}
#Override
public String getFirstName(String userName) {
// TODO Auto-generated method stub
String sql = "select u.FirstName from Users u where u.Username = ? ";
Object[] params = new Object[] { userName };
String firstName = (String)getJdbcTemplate().queryForObject(sql, params, String.class);
return firstName;
}
}
So I don't really get to use these already written methods to update the data and get these changes in user profile.
I am new to Ajax so I'm glad to get any help.
You are wrong on your JSP, the j_spring_security_check is default URL Spring Login.
For updating firstname you must do #RequestMapping #ResponseBody on your Controller de handle the Ajax Request.
Hi I have a json file stored in the project folder "project/file.json". How can I first, access and read the json file's data from the servlet's doGet()method. Second I want to print the returned data in a separate JSP file. I'm posting here as the last resort since I could not find anything on how to do this. here is my files and my attempt so far
here is file.json
{
"person": {
"title": "manager",
"questions": [
"name ?",
"age ?",
"hobby ?"
]
}
}
here is the doGet () method from fileServlet.java
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
response.setContentType("text/json");
/* here I'm accessing the external file JSON file*/
getClass().getResourceAsStream("project/file.json");
/* here is where I run into trouble. the StringReader() only
accepts strings and I cannot figure out how to read the table form
file.json here*/
JsonReader reader = Json.createReader(new StringReader(person));
/*the reader needs to be set inorder to create a JsonObject*/
JsonObject jsonObject = reader.readObject();
}
and finally, the JSP file. I want the file.json items to appear in this form like so
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<form>
"name ?" get displayed here <br>
<input type="text" name="firstname" value="">
<br>
"age ?" get displayed here <br>
<input type="text" name="age" value="">
<br>
"hobby ?" get displayed here <br>
<input type="text" name="hobby" value="">
<br><br>
<input type="submit" value="Done">
</form>
</body>
</html>
Any help or tips will be appreciated
When I am using Jquery with spring MVC I got an error at browser side "Bad Request" and control not going to the controller.While I am using simple form and sending a request to same controller then it is going.
Below is my code please tell me where am I going wrong?
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script src="files/jquery-1.10.2.js"></script>
<script src="files/jquery-1.10.2.min.js"></script>
<script type="text/javascript">
var isJpg = function(name) {
return name.match(/jpg$/i)
};
var isPng = function(name) {
return name.match(/png$/i)
};
$(document).ready(function() {
var file = $('[name="file"]');
var imgContainer = $('#imgContainer');
$('#btnUpload').on('click', function() {
var filename = $.trim(file.val());
if (!(isJpg(filename) || isPng(filename))) {
alert('Please browse a JPG/PNG file to upload ...');
return;
}
$.ajax({
url: 'FileData.htm',
type: "POST",
data: new FormData(document.getElementById("fileForm")),
enctype: 'multipart/form-data',
processData: false,
contentType: false
}).done(function(data) {
imgContainer.html('');
var img = '<img src="data:' + data.contenttype + ';base64,'
+ data.base64 + '"/>';
imgContainer.append(img);
}).fail(function(jqXHR, textStatus) {
//alert(jqXHR.responseText);
alert('File upload failed ...');
});
});
$('#btnClear').on('click', function() {
imgContainer.html('');
file.val('');
});
});
</script>
</head>
<body>
<!-- <form name="dlgContent" action="FileData.htm" id="dlgcon" enctype="multipart/form-data" method="POST">
<input type="file" name="excelfile"/>
<input type="submit"/>
</form> -->
<div>
<form id="fileForm">
<input type="file" name="file" />
<button id="btnUpload" type="button">Upload file</button>
<button id="btnClear" type="button">Clear</button>
</form>
<div id="imgContainer"></div>
</div>
</body>
</html>
And my Controller Class in spring mapping given below
#RequestMapping(value="/FileData.htm", method = RequestMethod.POST)
public void FileData(Model model, #RequestParam CommonsMultipartFile[] excelfile, HttpServletRequest request, HttpServletResponse response){
System.out.println("bhjsbfjhsbfbdesfbsfb");
response.setContentType("application/json");
FileData fd = new FileData();
//Map<String, String> data = fd.submitFileData(excelfile);
Gson gson = new Gson();
// String values = gson.toJson(data);
try {
//response.getWriter().write(values);
//System.out.println(values);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
Thanks.
Actually you are sending Json and not html you should use #ResponseBody
#RequestMapping(value="/upload", method = RequestMethod.POST)
public #ResponseBody
FileData upload(MultipartHttpServletRequest request,
#RequestParam String albumName,
HttpServletResponse response) {
Iterator<String> itr = request.getFileNames();
//others code here
Also Don't forget !! to config multipart data ,
Plus send back Object using jackson lib to jquery done function to be work
Gson lib is not good to use with #ResponseBody , we are using Gson with RestTemplate instead.