服务器之家

服务器之家 > 正文

Spring MVC+FastJson+Swagger集成的完整实例教程

时间:2021-04-24 11:18     来源/作者:vbirdbest

基础部分

1. fastjson 简介

fastjson是一个java库,可用于将java对象转换为json表示。它也可以被用来将一个json字符串转换成一个等效的java对象。在转换速度上应该是最快的,几乎成为了项目的标配(在ajax请求和接口开发时一般都会用fastjson而不再使用jackson)。

github: https://github.com/alibaba/fastjson

特性:

  • 在服务器端和android客户端提供最佳性能
  • 提供简单tojsonstring()和parseobject()方法的java对象转换为json,反之亦然
  • 允许存在的无法改变的对象转换为从json
  • java泛型的广泛支持
  • 允许自定义表示对象
  • 支持任意复杂的对象(深继承层次结构和广泛使用泛型类型)

主要特点:

  • 快速fast (比其它任何基于java的解析器和生成器更快,包括jackson)
  • 强大(支持普通jdk类包括任意java bean class、collection、map、date或enum)
  • 零依赖(没有依赖其它任何类库除了jdk)
  • 支持注解

2. fastjson api

fastjson api入口类是com.alibaba.fastjson.json,常用的序列化操作都可以在json类上的静态方法直接完成。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 把json文本parse为jsonobject或者jsonarray
public static final object parse(string text);
 
// 把json文本parse成jsonobject
public static final jsonobject parseobject(string text);
 
// 把json文本parse为javabean
public static final <t> t parseobject(string text, class<t> clazz);
 
// 把json文本parse成jsonarray
public static final jsonarray parsearray(string text);
 
// 把json文本parse成javabean集合
public static final <t> list<t> parsearray(string text, class<t> clazz);
 
// 将javabean序列化为json文本
public static final string tojsonstring(object object);
 
// 将javabean序列化为带格式的json文本
public static final string tojsonstring(object object, boolean prettyformat);
 
// 将javabean转换为jsonobject或者jsonarray
public static final object tojson(object javaobject);

jsonarray:相当于list<object>

jsonobject:相当于map<string, object>

serializeconfig: 是对序列化过程中一些序列化过程的特殊配置, 如对一些字段进行格式处理(日期、枚举等)

serializewriter:相当于stringbuffer

serializerfeature属性 :

  • quotefieldnames 输出key时是否使用双引号,默认为true
  • usesinglequotes 使用单引号而不是双引号,默认为false
  • writemapnullvalue 是否输出值为null的字段,默认为false
  • writeenumusingtostring enum输出name()或者original,默认为false
  • useiso8601dateformat date使用iso8601格式输出,默认为false
  • writenulllistasempty list字段如果为null,输出为[],而非null
  • writenullstringasempty 字符类型字段如果为null,输出为”“,而非null
  • writenullnumberaszero 数值字段如果为null,输出为0,而非null
  • writenullbooleanasfalse boolean字段如果为null,输出为false,而非null
  • skiptransientfield 如果是true,类中的get方法对应的field是transient,序列化时将会被忽略。默认为true
  • sortfield 按字段名称排序后输出。默认为false
  • writetabasspecial 把\t做转义输出,默认为false 不推荐
  • prettyformat 结果是否格式化,默认为false
  • writeclassname 序列化时写入类型信息,默认为false。反序列化是需用到
  • disablecircularreferencedetect 消除对同一对象循环引用的问题,默认为false
  • writeslashasspecial 对斜杠'/'进行转义
  • browsercompatible 将中文都会序列化为\uxxxx格式,字节数会多一些,但是能兼容ie 6,默认为false
  • writedateusedateformat 全局修改日期格式,默认为false。json.deffault_date_format = “yyyy-mm-dd”;json.tojsonstring(obj, serializerfeature.writedateusedateformat);
  • disablecheckspecialchar 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
  • notwriterootclassname 含义
  • beantoarray 将对象转为array输出
  • writenonstringkeyasstring
  • notwritedefaultvalue
  • browsersecure
  • ignorenonfieldgetter
  • writeenumusingname

实战部分

Spring MVC+FastJson+Swagger集成的完整实例教程

1、pom.xml 中引入spring mvc、 fastjson 依赖

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<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>
 
 <!-- 使用aliyun镜像 -->
 <repositories>
 <repository>
 <id>aliyun</id>
 <name>aliyun</name>
 <url>http://maven.aliyun.com/nexus/content/groups/public</url>
 </repository>
 </repositories>
 
 <build>
 <finalname>platform-springmvc-webapp</finalname>
 </build>
</project>

2、 配置web.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!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监听器</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-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、 配置spring-servlet.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?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" class="org.springframework.web.servlet.view.internalresourceviewresolver">
 <property name="prefix" value="/"></property> <!-- 视图文件的前缀 -->
 <property name="suffix" value=".jsp"></property> <!-- 视图文件的后缀名 -->
 <!-- view是用什么显示,这里是jsp,还可以用velocity之类的 -->
 <property name="viewclass" value="org.springframework.web.servlet.view.jstlview"></property>
 </bean>
 
 <!-- 启动spring mvc的注解功能,完成请求和注解pojo的映射 -->
 <mvc:annotation-driven>
 <mvc:message-converters register-defaults="true">
 <!-- 配置fastjson 替换原来的jackson支持 -->
 <bean class="com.alibaba.fastjson.support.spring.fastjsonhttpmessageconverter">
 <property name="supportedmediatypes">
 <list>
 <value>text/html;charset=utf-8</value>
 <value>application/json</value>
 </list>
 </property>
 <property name="features">
 <list>
 
 <value>quotefieldnames</value> <!-- 输出key时是否使用双引号,默认为true -->
 <value>writemapnullvalue</value> <!-- 是否输出值为null的字段,默认为false -->
 
 <!--
 <value>disablecircularreferencedetect</value>
 <value>writedateusedateformat</value>
 <value>writenullstringasempty</value> 字符类型字段如果为null,输出为"",而非null
 <value>writenullnumberaszero</value> 数值字段如果为null,输出为0,而非null
 <value>writenullbooleanasfalse</value> boolean字段如果为null,输出为false,而非null
 <value>writenulllistasempty</value> list字段如果为null,输出为[],而非null
 -->
 
 </list>
 </property>
 </bean>
 </mvc:message-converters>
 </mvc:annotation-driven>
</beans>

4、java

education:学历(枚举类)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.mengdee.manage.entity;
import java.util.hashmap;
import java.util.map;
/**
 * 学历
 * @author administrator
 *
 */
public enum education {
 kindergarten("幼儿园", 1),
 elementary("小学", 2),
 junior_middle("初级中学", 3),
 senior_middle("高级中学", 4),
 university("大学", 5),
 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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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; // 性别 1:男 2:女
 private short age; // 年龄
 private long salary; // 薪水
 private double weight; // 体重
 private char level; // 评级
 
 private boolean adult; // 是否成年人
 private date birthday; // 生日
 private education education;// 学历
 
 private string[] hobbies; // 爱好
 private list<dog> dogs; // 宠物狗
 private map<string, object> address; // 住址
 
 // 使用注解控制是否要序列化
 @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;
 }
 
 // 处理序列化枚举类型,默认的值是序列化枚举值字符串,而不是枚举绑定的索引或者文本
 @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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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;
 
@controller
public 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);
 
 // 使用该方式值为null的经测试不出来,已经配置了<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)默认是毫秒数"birthday":1495073314780,
 
// 使用serializeconfig序列号配置对日期格式化
// "{"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); // 枚举
 
 string[] hobbies = {"读书", "旅游"};
 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, "上海浦东新区");
 address address2 = new address(2l, "上海宝山区");
 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集成

第一步:引入相关依赖

?
1
2
3
4
5
6
7
8
9
10
11
<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>

第二步:swagger信息配置

swaggerconfig.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@configuration
@enablewebmvc
@enableswagger2
public 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("小明", "http://www.baidu.com", "baidu@163.com");
 return new apiinfo("api接口", //大标题 title
 "api接口", //小标题
 "0.0.1", //版本
 "www.baidu.com",//termsofserviceurl
 contact,//作者
 "api接口",//链接显示文字
 "http://www.baidu.com"//网站链接
 );
 }
}

注意:因swaggerconfig这个类配置了注解,所以这个类必须被扫描到,即该类一定包含在context:component-scan中。

第三步:在类、方法、参数上使用注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@controller
@requestmapping("/api/v1")
@api(description = "api接口")
public class apicontroller {
 @apioperation(value = "用户登录", notes = "用户登录接口")
 @apiresponses({
 @apiresponse(code = 0, message = "success"),
 @apiresponse(code = 10001, message = "用户名错误", response = illegalargumentexception.class),
 @apiresponse(code = 10002, message = "密码错误")
 })
 @requestmapping(value = "/user/login", method = requestmethod.post, produces = {"application/json;charset=utf-8;"})
 @responsebody
 public string login(@apiparam(name = "username", value = "用户名", required = true) @requestparam string username,
  @apiparam(name = "password", value = "密码", required = true) @requestparam string password){
 return "{'username':'" + username + "', 'password':'" + password + "'}";
 }
 
 
 @apiimplicitparams({
 @apiimplicitparam(paramtype = "header", name = "phone", datatype = "string", required = true, value = "手机号"),
 @apiimplicitparam(paramtype = "query", name = "nickname", datatype = "string", required = true, value = "nickname", defaultvalue = "双击666"),
 @apiimplicitparam(paramtype = "path", name = "platform", datatype = "string", required = true, value = "平台", defaultvalue = "pc"),
 @apiimplicitparam(paramtype = "body", name = "password", datatype = "string", required = true, value = "密码")
 })
 @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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class pager {
 @apimodelproperty(value = "页码", required = true)
 private int page;
 @apimodelproperty(value = "每页条数", 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;
 }
}

常用注解:

  • @api(description = “接口类的描述”)
  • @apioperation(value = “接口方法的名称”, notes = “备注说明”)
  • @apiparam(name = “参数名称”, value = “备注说明”, required = 是否必须):标注在方法的参数上 用于描述参数的名称、备注、是否必须等信息
  • @apiimplicitparam(paramtype = “query”, name = “password”, datatype = “string”, required = true, value = “密码”, defaultvalue = “123456”)用于描述方法的参数,标注在方法上,和@apiparam功能一样,只是标注的位置不同而已
         .paramtype:参数类型,即参数放在哪个地方
                .   header–>请求参数的获取:@requestheader,参数放在请求头
                 .   query–>请求参数的获取:@requestparam,参数追加在url后面
                 .   path(用于restful接口)–>请求参数的获取:@pathvariable
                 .   body 使用@requestbody接收数据 post有效,参数放在请求体中
                 .    form
        .name:参数名
        .datatype:参数的数据类型
        .required:参数是否必须传
        .value:参数的描述
        .defaultvalue:参数的默认值
  • @apiimplicitparams: 用于包含多个@apiimplicitparam
  • @apiresponse(code = 0, message = “success”),
         .code:响应码,例如400
         .message:信息,一般是对code的描述
         .response:抛出异常的类
  • @apimodel:描述一个model的信息(这种一般用在post创建的时候,使用@requestbody这样的场景,请求参数无法使用@apiimplicitparam注解进行描述的时候)
         .@apimodelproperty:描述一个model的属性
                  .   position 允许在模型中显式地排序属性。
                  .   value 参数名称
                  .   required 是否必须 boolean
                  .   hidden 是否隐藏 boolean
                  .   allowablevalues = “range[0, 1]” 一般用于指定参数的合法值
  • @apiignore:用于或略该接口,不生成该接口的文档

第四步:访问/v2/api-docs

在浏览器上访问http://localhost:8080/工程名称/v2/api-docs 如果有json内容,证明正常

Spring MVC+FastJson+Swagger集成的完整实例教程

第五步:下载swagger-ui

从github上下载https://github.com/swagger-api/swagger-ui,注意这里要选择下载v2.2.10(https://github.com/swagger-api/swagger-ui/tree/v2.2.10 ),大于这个版本的集成方式不一样。

集成方法:将v2.2.10下的dist目录下的所有文件放到自己工程中静态文件中,并使用下面代码覆盖掉index.html中的脚本部分

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<script type="text/javascript">
 var baseurl = "";
 $(function () {
  var url = window.location.search.match(/url=([^&]+)/);
  if (url && url.length > 1) {
  url = decodeuricomponent(url[1]);
  } else {
  //上面描述的api-docs地址
  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
  });
 
  //这里可以添加权限认证,例如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>

第六步:访问上面修改的那个index.html
http://localhost:8080/工程名称/static/third-party/swagger-ui/index.html

注意:因要访问静态资源,使用springmvc请确保静态资源能够被访问到,如果不能访问请做如下配置:

1、 在spring的配置文件中增加默认的servlet处理器

?
1
2
<!-- 过滤静态资源 -->
<mvc:default-servlet-handler/>

2、 在web.xml中增加要过滤的静态文件

?
1
2
3
4
5
6
7
8
<!-- 过滤静态资源 -->
<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>

Spring MVC+FastJson+Swagger集成的完整实例教程

示例项目代码结构:

Spring MVC+FastJson+Swagger集成的完整实例教程

完整示例demo下载地址:platform-springmvc-webapp.rar

其他

关于spring-servlet.xml 和 applicationcontext.xml

springmvc 提供了两种配置文件 spring-servlet.xml 、 applicationcontext.xml
spring-servlet.xml 是controller级别的,作用范围是控制层,默认的名字是【servlet-name】-servlet.xml
默认是放在web-inf/目录下,springmvc会自动加载,也可以在web.xml中配置它的位置

?
1
2
3
4
5
6
7
8
9
<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>

一般在spring-servlet.xml中配置一些和控制器相关的配置,如视图解析、静态资源文件的映射、返回结果的解析等

视图解析

  • org.springframework.web.servlet.view.urlbasedviewresolver
  • tiles3: org.springframework.web.servlet.view.tiles3.tilesconfigurer
  • springmvc: org.springframework.web.servlet.view.internalresourceviewresolver,
  • shiro: org.apache.shiro.spring.security.interceptor.authorizationattributesourceadvisor
  • 上传 org.springframework.web.multipart.commons.commonsmultipartresolver,

静态资源映射

?
1
2
3
4
5
6
<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

返回结果的解析

  • fastjson: com.alibaba.fastjson.support.spring.fastjsonhttpmessageconverter

3、applicationcontext.xml 是系统级别的配置,作用范围是系统上下文,它的初始化需要放到 web.xml 中的context-param中配置

?
1
2
3
4
<context-param>
 <param-name>contextconfiglocation</param-name>
 <param-value>classpath:conf/spring/spring-*.xml</param-value>
</context-param>

4、 关于applicationcontxt.xml,一般是按照功能拆成多个配置文件如:

  • - applicationcontxt-base.xml // 基础
  • - applicationcontxt-redis.xml // redis相关配置
  • - applicationcontxt-shiro.xml // shiro 相关配置
  • - applicationcontxt-dao.xml // 数据库相关配置
  • - applicationcontxt-xxx.xml // xxx

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://blog.csdn.net/vbirdbest/article/details/72472149

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
返回顶部