激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - SpringBoot中的內(nèi)容協(xié)商器圖解

SpringBoot中的內(nèi)容協(xié)商器圖解

2021-02-23 11:11波波維奇 Java教程

本文通過圖文解說加代碼的形式給大家介紹了SpringBoot中的內(nèi)容協(xié)商器知識(shí),需要的朋友參考下吧

背景

使用了restful的小伙伴對(duì)于導(dǎo)出這些需求本能就是拒絕的~破壞了restful的url的一致性【嚴(yán)格矯正 不是http json就是restful 很多小伙伴都會(huì)吧暴露出一個(gè)json就直接稱為restful 】

正如上文的代碼生成器 我們會(huì)批量生成一堆代碼 其中絕大部分都是restcontroller

?
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
public abstract class abstractrestcontroller<v extends vo, s extends so, pk extends serializable> {
  protected class<v> voclazz;
  @autowired
  private service<v, s, pk> service;
  public abstractrestcontroller() {
    typetoken<v> votype = new typetoken<v>(getclass()) {
    };
    voclazz = (class<v>) votype.getrawtype();
  }
  @postmapping()
  @apioperation(value = "新建實(shí)體", notes = "")
  public result add(@requestbody v vo) {
    service.saveselective(vo);
    return resultgenerator.gensuccessresult();
  }
  @deletemapping("/{id}")
  @apioperation(value = "刪除實(shí)體", notes = "")
  public result delete(@pathvariable pk id) {
    service.deletebyid(id);
    return resultgenerator.gensuccessresult();
  }
  @putmapping
  @apioperation(value = "更新實(shí)體", notes = "")
  public result update(@requestbody v vo) {
    service.updatebyprimarykeyselective(vo);
    return resultgenerator.gensuccessresult();
  }
  @getmapping
  @apioperation(value = "獲取實(shí)體列表", notes = "")
  public result list(s so) {
    pagehelper.startpage(so.getcurrentpage(), so.getpagesize());
    list<v> list = service.findall();
    pageinfo pageinfo = new pageinfo(list);
    excelexportparam();
    return resultgenerator.gensuccessresult(pageinfo);
  }
  protected void excelexportparam() {
    exportparams ep = new exportparams(null, "數(shù)據(jù)");
    excelexportparam<v> param = new excelexportparam<>();
    param.setclazz(voclazz);
    param.setexcelexport(excelexport.normalexcel);
    param.setexportparams(ep);
    param.setfilename("文件.xls");
    f6static.setexcelexportparam(param);
  }
  @getmapping("/{id}")
  @apioperation(value = "獲取單個(gè)實(shí)體", notes = "")
  public result detail(@pathvariable pk id) {
    v vo = service.findbyid(id);
    return resultgenerator.gensuccessresult(vo);
  }
  @deletemapping("/batch")
  @apioperation(value = "批量刪除實(shí)體", notes = "")
  public result batchdelete(@requestparam string ids) {
    service.deletebyids(ids);
    return resultgenerator.gensuccessresult();
  }
  @getmapping("/batch")
  @apioperation(value = "批量獲取實(shí)體", notes = "")
  public result batchdetail(@requestparam string ids) {
    list<v> vos = service.findbyids(ids);
    return resultgenerator.gensuccessresult(vos);
  }
  @postmapping("/batch")
  @apioperation(value = "批量新建實(shí)體", notes = "")
  public result add(@requestbody list<v> vos) {
    service.save(vos);
    return resultgenerator.gensuccessresult();
  }
  @getmapping("/count")
  @apioperation(value = "獲取實(shí)體數(shù)目", notes = "")
  public result count(@requestbody v v) {
    int count = service.selectcount(v);
    return resultgenerator.gensuccessresult(count);
  }

那么導(dǎo)出如何做呢?【其實(shí)可以理解成導(dǎo)出就是數(shù)據(jù)的展示 不過此時(shí)結(jié)果不是json而已】

拋出一個(gè)問題那么登錄登出呢?傳統(tǒng)的方案都是login logout 那么換成restful資源的思路是啥呢?

提示: 登錄就是session的新建 登出就是session的刪除

實(shí)現(xiàn)

基于上述思路 我們自然就想到了那么我們只需要對(duì)同一個(gè)url返回多種結(jié)果不就ok了?【pdf一個(gè)版本 json一個(gè)版本 xml一個(gè)版本 xls一個(gè)版本】

bingo!這個(gè)是內(nèi)容協(xié)商器的由來

內(nèi)容協(xié)商器并不是spring創(chuàng)造出來的 事實(shí)上這個(gè)從http頭里面也能看出

SpringBoot中的內(nèi)容協(xié)商器圖解

1.比如給英語(yǔ)客戶返回英語(yǔ)頁(yè)面 過于客戶返回漢語(yǔ)頁(yè)面

http 協(xié)議中定義了質(zhì)量值(簡(jiǎn)稱 q 值),允許客戶端為每種偏好類別列出多種選項(xiàng),并為每種偏好選項(xiàng)關(guān)聯(lián)一個(gè)優(yōu)先次序。

?
1
accept-language: en;q=0.5, fr;q=0.0, nl;q=1.0, tr;q=0.0

其中 q 值的范圍從 0.0 ~ 1.0(0.0 是優(yōu)先級(jí)最低的,而 1.0 是優(yōu)先級(jí)最高的)。

注意,偏好的排列順序并不重要,只有與偏好相關(guān)的 q 值才是重要的

2.那么還有其他的一些參數(shù) 比如 accept-header

通常是先內(nèi)容協(xié)商器有如下幾種方案

1.使用accept header:

這一種為教科書中通常描述的一種,理想中這種方式也是最好的,但如果你的資源要給用戶直接通過瀏覽器訪問(即html展現(xiàn)),那么由于瀏覽器的差異,發(fā)送上來的accept header頭將是不一樣的. 將導(dǎo)致服務(wù)器不知要返回什么格式的數(shù)據(jù)給你. 下面是瀏覽器的accept header   

?
1
2
3
4
5
6
chrome:
   accept:application/xml,application/xhtml+xml,textml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5    
   firefox:
   accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8     
   ie8:
   accept:image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-silverlight, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*

2.使用擴(kuò)展名

喪失了同一url多種展現(xiàn)的方式,但現(xiàn)在這種在實(shí)際環(huán)境中是使用最多的.因?yàn)楦臃铣绦騿T的審美觀.

比如/user.json /user.xls /user.xml

使用參數(shù) 現(xiàn)在很多open api是使用這種方式,比如淘寶

但是對(duì)于不同瀏覽器可能accept-header并不是特別統(tǒng)一 因此許多實(shí)現(xiàn)選擇了2 3兩種方案

我們?cè)趕pring中采用上述兩種方案

首先配置內(nèi)容協(xié)商器

代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@bean
  public viewresolver contentnegotiatingviewresolver(
      contentnegotiationmanager manager) {
    // define the view resolvers
    viewresolver beannameviewresolver = new beannameviewresolver();
    list<viewresolver> resolvers = lists.newarraylist(beannameviewresolver);
    contentnegotiatingviewresolver resolver = new contentnegotiatingviewresolver();
    resolver.setviewresolvers(resolvers);
    resolver.setcontentnegotiationmanager(manager);
    return resolver;
  }
  @override
  public void configurecontentnegotiation(contentnegotiationconfigurer configurer) {
    configurer.favorpathextension(true)
        .usejaf(false)
        .favorparameter(true)
        .parametername("format")
        .ignoreacceptheader(true)
        .defaultcontenttype(mediatype.application_json)
        .mediatype("json", mediatype.application_json)
        .mediatype("xls", excel_media_type);
  }

創(chuàng)建對(duì)應(yīng)的轉(zhuǎn)換器

?
1
2
3
4
private httpmessageconverter<object> createexcelhttpmessageconverter() {
  excelhttpmessageconverter excelhttpmessageconverter = new excelhttpmessageconverter();
  return excelhttpmessageconverter;
}

直接使用easy-poi導(dǎo)出數(shù)據(jù)

?
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
/*
 * copyright (c) 2017. lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * morbi non lorem porttitor neque feugiat blandit. ut vitae ipsum eget quam lacinia accumsan.
 * etiam sed turpis ac ipsum condimentum fringilla. maecenas magna.
 * proin dapibus sapien vel ante. aliquam erat volutpat. pellentesque sagittis ligula eget metus.
 * vestibulum commodo. ut rhoncus gravida arcu.
 */
package com.f6car.base.web.converter;
import cn.afterturn.easypoi.excel.excelexportutil;
import com.f6car.base.common.result;
import com.f6car.base.core.excelexport;
import com.f6car.base.core.excelexportparam;
import com.github.pagehelper.pageinfo;
import com.google.common.collect.lists;
import org.apache.poi.ss.usermodel.workbook;
import org.springframework.http.httpheaders;
import org.springframework.http.httpinputmessage;
import org.springframework.http.httpoutputmessage;
import org.springframework.http.mediatype;
import org.springframework.http.converter.abstracthttpmessageconverter;
import org.springframework.http.converter.generichttpmessageconverter;
import org.springframework.http.converter.httpmessagenotreadableexception;
import org.springframework.http.converter.httpmessagenotwritableexception;
import java.io.ioexception;
import java.lang.reflect.type;
import java.net.urlencoder;
import java.util.collection;
import java.util.collections;
import java.util.map;
import static com.f6car.base.core.f6static.getexcelexportparam;
/**
 * @author qixiaobo
 */
public class excelhttpmessageconverter extends abstracthttpmessageconverter<object>
    implements generichttpmessageconverter<object> {
  public static final mediatype excel_media_type = new mediatype("application", "vnd.ms-excel");
  public excelhttpmessageconverter() {
    super(excel_media_type);
  }
  @override
  protected boolean supports(class<?> clazz) {
    return false;
  }
  @override
  protected object readinternal(class<?> clazz, httpinputmessage inputmessage) throws ioexception, httpmessagenotreadableexception {
    return null;
  }
  @override
  protected void writeinternal(object o, httpoutputmessage outputmessage) throws ioexception, httpmessagenotwritableexception {
    httpheaders headers = outputmessage.getheaders();
    collection data = getactualdata((result) o);
    excelexportparam excelexportparam = getexcelexportparam();
    workbook workbook;
    switch (excelexportparam.getexcelexport()) {
      case normalexcel:
        workbook = excelexportutil.exportexcel(
            excelexportparam.getexportparams(),
            (class<?>) excelexportparam.getclazz(),
            (collection<?>) data);
        break;
      case mapexcel:
        workbook = excelexportutil.exportexcel(
            excelexportparam.getexportparams(),
            excelexportparam.getexcelexportentities(),
            (collection<? extends map<?, ?>>) data);
        break;
      case bigexcel:
      case mapexcelgraph:
      case pdftemplate:
      case templateexcel:
      case templateword:
      default:
        throw new runtimeexception();
    }
    if (workbook != null) {
      if (excelexportparam.getfilename() != null) {
        string codedfilename = urlencoder.encode(excelexportparam.getfilename(), "utf8");
        headers.setcontentdispositionformdata("attachment", codedfilename);
      }
      workbook.write(outputmessage.getbody());
    }
  }
  private collection getactualdata(result r) {
    if (r != null && r.getdata() != null) {
      object data = r.getdata();
      if (data instanceof pageinfo) {
        return ((pageinfo) data).getlist();
      } else if (!(data instanceof collection)) {
        data = lists.newarraylist(data);
      } else {
        return (collection) data;
      }
    }
    return collections.emptylist();
  }
  @override
  public boolean canread(type type, class<?> contextclass, mediatype mediatype) {
    //不支持excel
    return false;
  }
  @override
  public object read(type type, class<?> contextclass, httpinputmessage inputmessage) throws ioexception, httpmessagenotreadableexception {
    return null;
  }
  @override
  public boolean canwrite(type type, class<?> clazz, mediatype mediatype) {
    return super.canwrite(mediatype) && clazz == result.class && support();
  }
  private boolean support() {
    excelexportparam param = getexcelexportparam();
    if (param == null || param.getexcelexport() == null || param.getexportparams() == null) {
      return false;
    }
    if (param.getexcelexport() == excelexport.normalexcel) {
      return true;
    } else {
      logger.warn(param.getexcelexport() + " not supprot now!");
      return false;
    }
  }
  @override
  public void write(object o, type type, mediatype contenttype, httpoutputmessage outputmessage) throws ioexception, httpmessagenotwritableexception {
    super.write(o, contenttype, outputmessage);
  }
}

暫時(shí)只是針對(duì)導(dǎo)出 因此在使用的時(shí)候如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@getmapping
 @apioperation(value = "獲取實(shí)體列表", notes = "")
 public result list(s so) {
   pagehelper.startpage(so.getcurrentpage(), so.getpagesize());
   list<v> list = service.findall();
   pageinfo pageinfo = new pageinfo(list);
   excelexportparam();
   return resultgenerator.gensuccessresult(pageinfo);
 }
 protected void excelexportparam() {
   exportparams ep = new exportparams(null, "數(shù)據(jù)");
   excelexportparam<v> param = new excelexportparam<>();
   param.setclazz(voclazz);
   param.setexcelexport(excelexport.normalexcel);
   param.setexportparams(ep);
   param.setfilename("文件.xls");
   f6static.setexcelexportparam(param);
 }

當(dāng)我們?cè)L問時(shí)如下

 

SpringBoot中的內(nèi)容協(xié)商器圖解

?
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
186
187
188
189
190
191
192
193
194
195
196
197
{
 "code": 200,
 "data": {
 "endrow": 10,
 "firstpage": 1,
 "hasnextpage": true,
 "haspreviouspage": false,
 "isfirstpage": true,
 "islastpage": false,
 "lastpage": 8,
 "list": [
 {
 "cellphone": "13857445502",
 "idemployee": 24201883434352650,
 "idownorg": 23993199378825296,
 "idrole": 88,
 "idwxbstation": "332",
 "idwxbuser": "207",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 23993199378825296,
 "username": "lingweiqiche"
 },
 {
 "cellphone": "",
 "idemployee": 0,
 "idownorg": 9999,
 "idrole": 4,
 "idwxbstation": "",
 "idwxbuser": "",
 "isadmin": 0,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434356532,
 "username": "007"
 },
 {
 "cellphone": "15715139000",
 "idemployee": 24351585207523460,
 "idownorg": 24201883434357600,
 "idrole": 89,
 "idwxbstation": "540",
 "idwxbuser": "298",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434357600,
 "username": "15715139000"
 },
 {
 "cellphone": "",
 "idemployee": 0,
 "idownorg": 24201883434357600,
 "idrole": 216,
 "idwxbstation": "",
 "idwxbuser": "",
 "isadmin": 0,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434357920,
 "username": "sunlingli"
 },
 {
 "cellphone": "",
 "idemployee": 24351585207425676,
 "idownorg": 24201883434359384,
 "idrole": 90,
 "idwxbstation": "348",
 "idwxbuser": "227",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "opzuds_v13we500kxymj6xg_gfee",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434359388,
 "username": "15952920979"
 },
 {
 "cellphone": "",
 "idemployee": 0,
 "idownorg": 24201883434359790,
 "idrole": 91,
 "idwxbstation": "315",
 "idwxbuser": "175",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434359790,
 "username": "13809056211"
 },
 {
 "cellphone": "18903885585",
 "idemployee": 24201883434366164,
 "idownorg": 24201883434359890,
 "idrole": 92,
 "idwxbstation": "317",
 "idwxbuser": "178",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434359892,
 "username": "18903885585"
 },
 {
 "cellphone": "",
 "idemployee": 24351585207425668,
 "idownorg": 24201883434359924,
 "idrole": 93,
 "idwxbstation": "318",
 "idwxbuser": "179",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434359930,
 "username": "13372299595"
 },
 {
 "cellphone": "",
 "idemployee": 0,
 "idownorg": 24201883434360052,
 "idrole": 94,
 "idwxbstation": "321",
 "idwxbuser": "188",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434360052,
 "username": "15221250005"
 },
 {
 "cellphone": "",
 "idemployee": 0,
 "idownorg": 24201883434360070,
 "idrole": 95,
 "idwxbstation": "325",
 "idwxbuser": "198",
 "isadmin": 1,
 "isdel": 0,
 "isguideopen": 0,
 "limitmac": 0,
 "openid": "",
 "password": "96e79218965eb72c92a549dd5a330112",
 "pkid": 24201883434360070,
 "username": "13837251167"
 }
 ],
 "navigatefirstpage": 1,
 "navigatelastpage": 8,
 "navigatepages": 8,
 "navigatepagenums": [
 1,
 2,
 3,
 4,
 5,
 6,
 7,
 8
 ],
 "nextpage": 2,
 "orderby": "",
 "pagenum": 1,
 "pagesize": 10,
 "pages": 102,
 "prepage": 0,
 "size": 10,
 "startrow": 1,
 "total": 1012
 },
 "message": "success"
 }

當(dāng)訪問http://127.0.0.1:8079/zeus/user?format=xls 或者h(yuǎn)ttp://127.0.0.1:8079/zeus/user.xls

如下效果

SpringBoot中的內(nèi)容協(xié)商器圖解

SpringBoot中的內(nèi)容協(xié)商器圖解

由于這邊的數(shù)據(jù)和查詢有關(guān) 因此我們可以這樣操作http://127.0.0.1:8079/zeus/user.xls?pagesize=1000 輕而易舉實(shí)現(xiàn)了查詢結(jié)果xls化!

SpringBoot中的內(nèi)容協(xié)商器圖解

SpringBoot中的內(nèi)容協(xié)商器圖解

總結(jié)

以上所述是小編給大家介紹的springboot中的內(nèi)容協(xié)商器圖解,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://www.jianshu.com/p/f7b257585d9a

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本aaa一级片 | 欧美一级视频免费看 | 亚洲一区二区成人 | 亚洲综合中文 | 狠狠撸电影 | 精品国产一区二 | 久草在线视频免费播放 | 在线观看国产网站 | 亚洲欧美日韩精品久久 | 一级一片免费 | 免费看日韩片 | 国产99久久久久久免费看 | 中国产一级毛片 | 免费国产不卡午夜福在线 | 黄色网址免费进入 | 关键词| 国产免费一区二区三区在线能观看 | 国产中出视频 | 日本一区二区精品视频 | 天海翼四虎精品正在播放 | 精品一区二区三区在线视频 | 黄色片视频免费观看 | 天天鲁在线视频免费观看 | 欧美一级片免费在线观看 | 91精品国产99久久久久久红楼 | 久久久av亚洲男天堂 | 国产精品一区二区在线 | 特一级黄色毛片 | 亚洲网站在线播放 | 一区二区三区手机在线观看 | 在线看成人av | 欧美综合在线观看视频 | 亚洲成人免费电影 | 成人在线视频在线观看 | 成人毛片在线 | 欧美人成在线视频 | 日韩精品中文字幕一区 | 黄色毛片一级视频 | 97超碰资源站 | 国产成年人网站 | 欧美激情精品久久久久久黑人 |