I haven't wanted to use Session recently. I want to experience a safer and more stable way token, and write a unified interface for the browser and APP. So I changed the front desk of a training program to Ajax, and then jumped and used SpringMVC to control forwarding. I have a deeper understanding of transmitting JSON data. I will share it and please correct me.
In SpringMVC, we can choose several ways to accept JSON. Before talking about how SpringMVC accepts JSON, let’s talk about what JSON is. I won't elaborate on the specific definition. In JavaScript, we often define JSON objects in this way.
var jsonObject = {"username":"admin","password":123}In this form, we call it JSON object, and there is also a concept called JSON string. As the name suggests, a whole wrapped by '' or " ", we call it a string. We know that strings can be output directly, but objects cannot be output directly. So in JavaScript, we can
//Define an object jsonObjectvar jsonObject = {"username":"admin","password":123};alert(jsonObject);At this time, [object Object] will be displayed without outputting the content of the JSON object. JavaScript provides us with two tools
JSON.parse() is used to convert a JSON string into a JavaScript object. JSON.stringify() is used to convert JavaScript values to JSON strings.
So when we type
alert(JSON.stringify(jsonObject));
{"username":"admin","password":123} will be displayed;
* Okay, that's all for the explanation of JSON. Let's talk about SpringMVC *
Since JSON has the above two ways of existence, which one should we pass the value to SpringMVC through ajax?
We first try to send the JSON object directly
//Define json object var username = $("#username").val(); var password = $("#password").val(); var json = { "username" : username, "password" : password };// Jquery Ajax request $.ajax({ url : "jsontest", type : "POST", async : true, data : json, dataType : 'json', success : function(data) { if (data.userstatus === "success") { $("#errorMsg").remove(); } else { if ($("#errorMsg").length <= 0) { $("form[name=loginForm]").append(errorMsg); } } } } });Let's first think about what SpringMVC provides to us. There is an annotation of @RequestParam. For this annotation, its function is basically the same as the request.getParameter in our Servlet. We first use this annotation to get it
@RequestMapping("/jsontest") public void test(@RequestParam(value="username",required=true) String username, @RequestParam(value="password",required=true) String password){ System.out.println("username: " + username); System.out.println("password: " + password); }Our parameters successfully output from the background were successfully accepted!
SpringMVC is so smart, if we remove the @RequestParam annotation, what will happen if we put two values directly in?
@RequestMapping("/jsontest") public void test(String username,String password){ System.out.println("username: " + username); System.out.println("password: " + password); }It was actually successful. I won’t elaborate on the principle here. Interested friends can break the point and take a look.
SpringMVC provides a @RequestBody, which is used to process the data sent by the foreground definition Content-Type: not the application/x-www-form-urlencoded encoding, such as application/json, application/xml, etc.;
Careful friends may have discovered that in the previous Ajax, we did not define the Content-type type, and Jquery uses the application/x-www-form-urlencoded type by default. That means SpringMVC's @RequestParam annotation, and Servlet's request.getParameter can accept JSON objects transmitted in this format.
Why! ? I believe everyone is familiar with GET requests. It sends parameters to the server in the form of url?username=”admin”&password=123, and request.getParameter can receive this parameter. We can also see this in the browser address bar. As for the POST we use in Ajax and sends a JSON object, how do we get it in the background? The answer lies in the encoding method of Content-Type x-www-form-urlencoded converts JSON data into a string, (username=”admin”&password=123) and adds this string to the url and uses ? segmentation (is it very similar to the GET method). When the submission method is POST, the browser encapsulates the data into HTTP BODY and then sends it to the server. So it will not be displayed on the URL. (This paragraph may be a bit of a twist, I hope everyone can understand it carefully.)
Finally finished speaking, breathed a long sigh. So when we use the @RequestBody annotation, the Content-Type of the front desk must be changed to application/json. If there is no change, the front desk will report an error of 415 (Unsupported Media Type). The background log will report an error Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported. These errors will not be displayed in Tomcat under Eclipse. It will only be displayed when the log is used. You can read my previous article on how to configure the log. Next, let's configure it correctly. The above mentioned that Content-Type needs to be changed, and our data must also be changed. This annotation method only accepts JSON strings instead of JSON objects.
$.ajax({ url : "jsontest", type : "POST", async : true, contentType : "application/json", data : JSON.stringify(json), dataType : 'json', success : function(data) { if (data.userstatus === "success") { $("#errorMsg").remove(); } else { if ($("#errorMsg").length <= 0) { $("form[name=loginForm]").append(errorMsg); } } } });The background also changes. Json can actually be understood as a key-value pair, so we use Map to receive it and then further process the string or other data types.
@RequestMapping("/jsontest") public void test(@RequestBody(required=true) Map<String,Object> map ){ String username = map.get("username").toString(); String password = map.get("password").toString(); System.out.println("username: " + username); System.out.println("password: " + password); }At the same time, I remembered the magical SpringMVC again, so I decided to remove the annotation and try it. OK, I was decisively exploded with a null pointer error... I tried to stop it.
SpringMVC also provides a method to bind parameters directly to POJO, let's try it. The front desk is the same, so I won't post it.
@RequestMapping("/jsontest") public void test(@RequestBody User user ){ String username = user.getUsername(); String password = user.getPassword(); System.out.println("username: " + username); System.out.println("password: " + password); }OK, this time you can get the value. I personally don’t like this method for uploading small data volumes like login. There are many variables in the User. I only used two of them. There is no need to create a User object. Generally, when the data volume is small, I still prefer to use separate values to get it. Let's think about it again, if we are uploading JSON objects, can we bind POJO? The answer is yes. Do not use the @RequestParam annotation, otherwise Required User parameter 'user' is not present error. The explanation is basically over here, let’s summarize it below.
We first talk about JSON objects and JSON strings
Then when SpringMVC accepts two or two JSON formats, the front-end ContentType setting and whether the back-end uses annotations to accept it, it also mentioned a little Servlet.
When Ajax is uploaded in application/x-www-form-urlencoded format, it is necessary to use @RequestParam or Servlet to obtain it in the background. When Ajax is uploaded in application/json format, it is used to use JSON strings, the background needs to use @RquestBody to get it.
These are some summary of my experiments for a day. I hope it can help you. If there are any errors, please forgive me and correct me.
The above detailed explanation of JSON parameters accepted by SpringMVC and summary of common errors is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.