Basic parts
1. Introduction to FastJson
Fastjson is a Java library that can be used to convert Java objects into JSON representations. It can also be used to convert a JSON string into an equivalent Java object. It should be the fastest conversion speed and has almost become the standard configuration of projects (fastjson is usually used instead of jackson when ajax request and interface development).
GitHub: https://github.com/alibaba/fastjson (local download)
characteristic:
Main features:
2. fastjson api
The Fastjson API entry class is com.alibaba.fastjson.JSON. Common serialization operations can be directly completed by static methods on the JSON class.
// parse JSON text as JSONObject or JSONArray public static final Object parse(String text); // parse JSON text into JSONObject public static final JSONObject parseObject(String text); // parse JSON text as JavaBean public static final <T> T parseObject(String text, Class<T> clazz); // parse JSON text into JSONArray public static final JSONArray parseArray(String text); // parse the JSON text into JavaBean collection public static final <T> List<T> parseArray(String text, Class<T> clazz); // Serialize JavaBean into JSON text public static final String toJSONString(Object object); // Serialize JavaBean into formatted JSONString(Object object, boolean prettyFormat); // Convert JavaBean to JSONObject or JSONArraypublic static final Object toJSON(Object javaObject);
JSONArray: equivalent to List<Object>
JSONObject: equivalent to Map<String, Object>
SerializeConfig: is a special configuration for some serialization processes during the serialization process, such as formatting some fields (date, enumeration, etc.)
SerializeWriter: equivalent to StringBuffer
SerializerFeature property:
Practical part
1. Introduce spring mvc and fastjson dependencies in pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mengdee</groupId> <artifactId>platform-springmvc-webapp</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>platform-springmvc-webapp Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>3.8.1</junit.version> <log4j.version>2.5</log4j.version> <jstl.version>1.2</jstl.version> <spring.version>4.2.3.RELEASE</spring.version> <fastjson.version>1.2.32</fastjson.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!-- springframework --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> </dependencies> <!-- Using aliyun mirror--> <repositories> <repository> <id>aliyun</id> <name>aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </repository> </repository> </repository> </repository> <build> <finalName>platform-springmvc-webapp</finalName> </build></project>2. Configure web.xml
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app> <display-name>Archetype Created Web Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/spring/spring-*.xml</param-value> </context-param> <listener> <description>Spring listener</description> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-mapping> <servlet-name>spring-mvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>/index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>404</error-code> <location>/index.jsp</location> </error-page></web-app>
3. Configure spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="com.mengdee.manage.controller" /> <bean id="ViewResolver"> <property name="prefix" value="/"></property> <!-- Prefix of view file --> <property name="suffix" value=".jsp"></property> <!-- Suffix name="!-- What is the view used to display? Here is jsp, you can also use velocity and other things --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> </bean> <!-- Start Spring MVC annotation function to complete the mapping of requests and annotation POJOs --> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <!-- Configure Fastjson to replace the original jackson support--> <bean> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="features"> <list> <value>QuoteFieldNames</value> <!-- Whether to use double quotes when outputting key, default to true --> <value>WriteMapNullValue</value> <!-- Whether to output a field with a null value, default to false --> <!-- <value>DisableCircularReferenceDetect</value> <value>WriteDateUseDateFormat</value> <value>WriteNullStringAsEmpty</value> If the character type field is null, output is "", not null <value>WriteNullNumberAsZero</value> If the numeric field is null, the output is 0, not null <value>WriteNullBooleanAsFalse</value> Boolean field is null, the output is false, not null <value>WriteNullListAsEmpty</value> List field is null, the output is [], not null --> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven></beans>
4. Java
Education: Education (enumeration class)
package com.mengdee.manage.entity;import java.util.HashMap;import java.util.Map;/** * Education* @author Administrator * */public enum Education { KINDERGARTEN("Kindergarten", 1), ELEMENTARY("Elementary School", 2), JUNIOR_MIDDLE("Junior High School", 3), SENIOR_MIDDLE("High School", 4), UNIVERSITY("University", 5), COLLEGE("College", 6); private static final Map<Integer, Education> EDUCATION_MAP = new HashMap<Integer, Education>(); static { for (Education education : Education.values()) { EDUCATION_MAP.put(education.getIndex(), education); } } private String text; private int index; private Education(String text, int index) { this.text = text; this.index = index; } public String getText() { return text; } public void setText(String text) { this.text = text; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public static Education getEnum(Integer index) { return EDUCATION_MAP.get(index); }}Person:
package com.mengdee.manage.entity;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Map;import com.alibaba.fastjson.annotation.JSONField;public class Person { private Long id; private String name; private byte gender; // Gender 1: Male 2: Female private short age; // Age private long salary; // Salary private double weight; // Weight private char level; // Rating private boolean adult; // Whether adult private Date birthday; // Birthday private Education education;// Educational qualification private String[] hobbies; // Hobbies private List<Dog> dogs; // Pet dog private Map<String, Object> address; // Address// Use annotations to control whether you want to serialize @JSONField(serialize = false) private List<Object> obj = new ArrayList<>(); public Person() { } public Person(Long id, String name, byte gender, short age, long salary, double weight, char level, boolean adult, Date birthday, String[] hobbies, List<Dog> dogs, Map<String, Object> address) { super(); this.id = id; this.name = name; this.gender = gender; this.age = age; this.salary = salary; this.weight = weight; this.level = level; this.adult = adult; this.birthday = birthday; this.hobbies = hobbies; this.dogs = dogs; this.address = address; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public byte getGender() { return gender; } public void setGender(byte gender) { this.gender = gender; } public short getAge() { return age; } public void setAge(short age) { this.age = age; } public long getSalary() { return salary; } public void setSalary(long salary) { this.salary = salary; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } public char getLevel() { return level; } public void setLevel(char level) { this.level = level; } public boolean isAdult() { return adult; } public void setAdult(boolean adult) { this.adult = adult; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } // Handle serialized enumeration types, the default value is serialized enum value string, rather than the enum binding index or text @JSONField(name = "edu") public int getEdu(){ return education.getIndex(); } @JSONField(name = "edu") public void setEdu(int index){ this.education = Education.getEnum(index); } @JSONField(serialize = false) public Education getEducation() { return education; } @JSONField(serialize = false) public void setEducation(Education education) { this.education = education; } public String[] getHobbies() { return hobbies; } public void setHobbies(String[] hobbies) { this.hobbies = hobbies; } public List<Dog> getDogs() { return dogs; } public void setDogs(List<Dog> dogs) { this.dogs = dogs; } public Map<String, Object> getAddress() { return address; } public void setAddress(Map<String, Object> address) { this.address = address; }}TestController
package com.mengdee.manage.controller;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.serializer.DoubleSerializer;import com.alibaba.fastjson.serializer.SerializeConfig;import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;import com.mengdee.manage.entity.Address;import com.mengdee.manage.entity.Dog;import com.mengdee.manage.entity.Education;import com.mengdee.manage.entity.Person;@Controllerpublic class TestController { private static SerializeConfig serializeConfig = new SerializeConfig(); static { serializeConfig.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss")); serializeConfig.put(Double.class, new DoubleSerializer(new DecimalFormat("0.00"))); } @RequestMapping("/index") public String index(){ return "index"; } // javabean to object @RequestMapping("/json") @ResponseBody public Object json(){ Person person = new Person(); person.setId(1L); person.setName("mengdee"); person.setAge((short) 18); // /* { "birthday": null, "weight": 0, "dogs": null, "adult": false, "hobbies": null, "education": null, "id": 1, "level": "", "address": null, "age": 18, "name": "mengdee", "gender": 0, "salary": 0 } */ Object personJson = JSON.toJSON(person); return personJson; } // javabean to string @RequestMapping("/json2") @ResponseBody public String json2(){ Person person = new Person(); person.setId(1L); person.setName("mengdee"); person.setAge((short) 18); // If the value of null is used, it cannot be tested. <value>WriteMapNullValue</value>// "{"adult":false,"age":18,"gender":0,"id":1,"level":"","name":"mengdee","salary":0,"weight":0.0}" String jsonString = JSON.toJSONString(person); return jsonString; } @RequestMapping("/json3") @ResponseBody public Object json3(){ Person person = new Person(); person.setId(1L); person.setName("mengdee"); person.setAge((short) 18); person.setBirthday(new Date()); Object personJson = JSON.toJSON(person); // JSON.toJSON(person) defaults to milliseconds "birthday":1495073314780,// Use serializeConfig serial number to configure formatting for dates // "{"birthday":"2017-05-18 10:19:55","weight":0.0,"adult":false,"id":1,"level":"","age":18,"name":"mengdee","gender":0,"salary":0}" String jsonString = JSON.toJSONString(personJson, serializeConfig); return jsonString; } @RequestMapping("/json4") @ResponseBody public Object json4(){ Person person = new Person(); person.setId(1L); person.setName("mengdee"); person.setAge((short) 18); person.setBirthday(new Date()); person.setEducation(Education.UNIVERSITY); // Enumeration String[] hobbies = {"reading", "tourism"}; person.setHobbies(hobbies); Dog dog1 = new Dog(1L, "dog1", (short)1); Dog dog2 = new Dog(2L, "dog2", (short)2); List<Dog> dogs = new ArrayList<>(); dogs.add(dog1); dogs.add(dog2); person.setDogs(dogs); Address address1 = new Address(1l, "Shanghai Pudong New District"); Address address2 = new Address(2l, "Shanghai Baoshan District"); Map<String, Object> addressMap = new HashMap<>(); addressMap.put(address1.getId() + "", address1); addressMap.put(address2.getId() + "", address2); person.setAddress(addressMap); Object personJson = JSON.toJSON(person); return personJson; } @RequestMapping("/json5") @ResponseBody public String json5(){ Dog dog1 = new Dog(1L, "dog1", (short)1); Dog dog2 = new Dog(2L, "dog2", (short)2); List<Dog> dogs = new ArrayList<>(); dogs.add(dog1); dogs.add(dog2); // List<T> -> JSON String jsonString = JSON.toJSONString(dogs, false); System.out.println(jsonString); // JSON -> List<T> List<Dog> parseArray = JSON.parseArray(jsonString, Dog.class); for (Dog dog : parseArray) { System.out.println(dog); } Map<String,Dog> map = new HashMap<String, Dog>(); map.put("dog1",new Dog(1L, "dog1", (short)1)); map.put("dog2",new Dog(2L, "dog2", (short)2)); map.put("dog3",new Dog(3L, "dog3", (short)3)); // Map -> JSON String mapJsonString = JSON.toJSONString(map,true); System.out.println(mapJsonString); // JSON -> Map @SuppressWarnings("unchecked") Map<String,Dog> map1 = (Map<String,Dog>)JSON.parse(mapJsonString); for (String key : map1.keySet()) { System.out.println(key + ":" + map1.get(key)); } // Array -> JSON String[] hobbies = {"a","b","c"}; String hobbiesString = JSON.toJSONString(hobbies,true); System.out.println(hobbies); // JSON -> Array JSONArray jsonArray = JSON.parseArray(hobbiesString); for (Object o : jsonArray) { System.out.println(o); } System.out.println(jsonArray); return jsonString; }}Swagger Integration
Step 1: Introduce related dependencies
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> <scope>compile</scope></dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.6</version></dependency>
Step 2: Swagger information configuration
SwaggerConfig.java
@Configuration@EnableWebMvc@EnableSwagger2public class SwaggerConfig { @Bean public Docket customDocket() { Docket docket = new Docket(DocumentationType.SWAGGER_2); docket.apiInfo(apiInfo()); docket.select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)); docket.select().paths(PathSelectors.regex("/api/.*")).build(); return docket; } private ApiInfo apiInfo() { Contact contact = new Contact("Xiao Ming", "http://www.baidu.com", "[email protected]"); return new ApiInfo("API interface", //Big title "API interface", //Subtitle "0.0.1", //version "www.baidu.com", //termsOfServiceUrl contact, //Author "API interface", //Link display text "http://www.baidu.com"//Website link); }}Note: Because the SwaggerConfig class configures annotations, this class must be scanned, that is, the class must be included in the context:component-scan.
Step 3: Use annotations on classes, methods, and parameters
@Controller@RequestMapping("/api/v1")@Api(description = "API interface")public class ApiController { @ApiOperation(value = "User login", notes = "User login interface") @ApiResponses({ @ApiResponse(code = 0, message = "success"), @ApiResponse(code = 10001, message = "User name error", response = IllegalArgumentException.class), @ApiResponse(code = 10002, message = "Password error") }) @RequestMapping(value = "/user/login", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8;"}) @ResponseBody public String login(@ApiParam(name = "username", value = "username", required = true) @RequestParam String username, @ApiParam(name = "password", value = "password", required = true) @RequestParam String password){ return "{'username':'" + username + "', 'password':'" + password + "'}"; } @ApiImplicitParams({ @ApiImplicitParam(paramType = "header", name = "phone", dataType = "String", required = true, value = "mobile number"), @ApiImplicitParam(paramType = "query", name = "nickname", dataType = "String", required = true, value = "nickname", defaultValue = "double-click 666"), @ApiImplicitParam(paramType = "path", name = "platform", dataType = "String", required = true, value = "platform", defaultValue = "PC"), @ApiImplicitParam(paramType = "body", name = "password", dataType = "String", required = true, value = "password") }) @RequestMapping(value = "/{platform}/user/regist", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8;"}) @ResponseBody public String regist(@RequestHeader String phone, @RequestParam String nickname, @PathVariable String platform, @RequestBody String password){ return "{'username':'" + phone + "', 'nickname':'" + nickname + "', 'platform': '" + platform + "', 'password':'"+password+"'}"; } @RequestMapping(value = "/user/list", method = RequestMethod.GET, produces = {"application/json;charset=UTF-8;"}) @ResponseBody public String getUserList(Pager pager){ return "[{'id': "+pager.getPage()+", 'username': 'zhangsan"+pager.getSize()+"'}]"; } @RequestMapping("/docs") @ApiIgnore public String test(){ return "api-docs"; }}Pager
public class Pager { @ApiModelProperty(value = "Page Number", required = true) private int page; @ApiModelProperty(value = "Number of per page", required = true) private int size; public Pager() { } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getSize() { return size; } public void setSize(int size) { this.size = size; }}Common annotations:
Step 4: Access /v2/api-docs
Visit http://localhost:8080/project name/v2/api-docs on the browser, if there is json content, it is normal
Step 5: Download swagger-ui
Download https://github.com/swagger-api/swagger-ui from github. Note that you need to select download v2.2.10 (https://github.com/swagger-api/swagger-ui/tree/v2.2.10 (local download)). The integration method that is greater than this version is different.
Integration method: Put all files in the dist directory under v2.2.10 into static files in your project, and use the following code to overwrite the script part in index.html
<script type="text/javascript"> var baseUrl = ""; $(function () { var url = window.location.search.match(/url=([^&]+)/); if (url && url.length > 1) { url = decodeURIComponent(url[1]); } else { //The api-docs address described above url = baseUrl + "/webapp/v2/api-docs"; } //Pre load translate... if (window.SwaggerTranslator) { window.SwaggerTranslator.translate(); } window.swaggerUi = new SwaggerUi({ url: url, validatorUrl: undefined, dom_id: "swagger-ui-container", supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'], onComplete: function (swaggerApi, swaggerUi) { if (typeof initOAuth == "function") { initOAuth({ clientId: "your-client-id", clientSecret: "your-client-secret-if-required", realm: "your-realms", appName: "your-app-name", scopeSeparator: ",", additionalQueryStringParams: {} }); } if (window.SwaggerTranslator) { window.SwaggerTranslator.translate(); } $('pre code').each(function (i, e) { hljs.highlightBlock(e) }); addApiKeyAuthorization(); }, onFailure: function (data) { log("Unable to Load SwaggerUI"); }, docExpansion: "none", jsonEditor: false, apisSorter: "alpha", defaultModelRendering: 'schema', showRequestHeaders: false }); //Add permission authentication can be added here, for example token function addApiKeyAuthorization() { var token = "you-token"; var tokenHeader = new SwaggerClient.ApiKeyAuthorization("token", token, "header"); window.swaggerUi.api.clientAuthorizations.add("token", tokenHeader); } window.swaggerUi.load(); function log() { if ('console' in window) { console.log.apply(console, arguments); } } }); </script> Step 6: Access the index.html modified above
http://localhost:8080/Project name/static/third-party/swagger-ui/index.html
Note: Because you want to access static resources, please make sure that static resources can be accessed using springmvc. If you cannot access, please make the following configuration:
1. Add the default servlet processor to Spring configuration file
<!-- Filter static resources--><mvc:default-servlet-handler/>
2. Add static files to filter in web.xml
<!-- Filtering static resources--><servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> <url-pattern>*.css</url-pattern> <url-pattern>/assets/*"</url-pattern> <url-pattern>/images/*</url-pattern></servlet-mapping>
Sample project code structure:
The complete example demo download address: http://xiazai.VeVB.COM/201804/yuanma/platform-springmvc-webapp(VeVB.COM).rar
other
About spring-servlet.xml and applicationContext.xml
SpringMVC provides two configuration files spring-servlet.xml and applicationContext.xml
spring-servlet.xml is Controller level, and its scope of action is the control layer. The default name is [servlet-name]-servlet.xml
By default, it is placed in WEB-INF/ directory. SpringMVC will automatically load, and it can also be configured in web.xml.
<servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
Generally, some controller-related configurations are configured in spring-servlet.xml, such as view resolution, mapping of static resource files, parsing of return results, etc.
View analysis
Static resource mapping
<mvc:resources location="/static/" mapping="/static/**" /><mvc:resources location="/images/" mapping="/static/**" /><mvc:resources location="/css/" mapping="/static/**" /><mvc:resources location="/js/" mapping="/static/**" /><mvc:resources location="/html/" mapping="/static/**" /> <mvc:resources location="/upload/" mapping="/static/**" />
org.springframework.context.support.ResourceBundleMessageSource
Result analysis
3. applicationContext.xml is a system-level configuration, and its scope of function is the system context. Its initialization needs to be configured in context-param in web.xml.
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/spring/spring-*.xml</param-value></context-param>
4. Regarding applicationContxt.xml, it is generally divided into multiple configuration files according to the function, such as:
Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.