arrière-plan
Les amis qui utilisent l'instinct reposant pour exporter ces besoins sont rejetés ~ Il détruit la cohérence des URL reposantes [la correction stricte est Http JSON ou RESTFul. De nombreux amis exposeront un JSON et l'appelleront directement RESTFul]
Comme dans le générateur de code ci-dessus, nous générerons un tas de codes, dont la plupart sont des contrôles de repos.
La classe abstraite publique AbstractreStController <V étend Vo, s s'étend, PK étend Serializable> {Classe protégée <v> voclazz; @Autowired Service privé <V, S, PK> Service; public abstractrestController () {TypeToken <v> votype = new TypeToken <v> (getClass ()) {}; voclazz = (classe <v>) votype.getRawType (); } @Postmapping () @apioperation (value = "new entité", notes = "") Résultat public Add (@Requestbody v Vo) {Service.Saveselective (vo); return resultGenerator.GensucCessResult (); } @Deletemapping ("/ {id}") @apioperation (value = "Delete Entity", notes = "") Résultat public Delete (@Pathvariable pk id) {Service.DeleteById (id); return resultGenerator.GensucCessResult (); } @Putmapping @apiOperation (value = "Update Entity", Notes = "") Public Result Update (@Requestbody v Vo) {Service.UpDateByprimaryKeySelective (VO); return resultGenerator.GensucCessResult (); } @Getmapping @apiOperation (value = "Get Entity List", Notes = "") Public Results List (S SO) {PageHelper.StartPage (so.getCurrentPage (), so.getPageSize ()); List <v> list = service.findall (); PageInfo pageInfo = new PageInfo (liste); ExceLexportParam (); return resultGenerator.GenSuccressResult (pageInfo); } protégé void excelexportParam () {exportParams ep = new exportParams (null, "data"); ExceLexportParam <v> param = new ExceLexportParam <> (); Param.SetClazz (Voclazz); param.setExcelExport (excelexport.normalexcel); param.setExportParams (EP); param.setFileName ("file.xls"); F6Static.sexcelExportParam (param); } @GetMapping ("/ {id}") @apiOperation (value = "Get Single Entity", Notes = "") Public Result Detail (@PathVariable PK ID) {v Vo = Service.FindById (id); return resultgenerator.gensuccessResult (vo); } @Deletemapping ("/ lot") @apiOperation (value = "Batch Delete Entity", notes = "") Résultat public BatchDelete (@RequestParam String ids) {Service.DeleteByids (ids); return resultGenerator.GensucCessResult (); } @GetMapping ("/ Batch") @APioperation (value = "Batch Get Entity", Notes = "") Résultat public BatchDetail (@RequestParam String ids) {list <v> vos = Service.FindByIds (ids); return resultGenerator.gensuccessResult (VOS); } @PostMapping ("/ Batch") @APIOperation (value = "Batch New Entity", Notes = "") Résultat public Add (@Requestbody List <V> VOS) {Service.Save (VOS); return resultGenerator.GensucCessResult (); } @Getmapping ("/ count") @apioperation (value = "Obtenez le nombre d'entités", notes = "") Count de résultat public (@Requestbody v V) {int count = service.SelectCount (v); return resultGenerator.gensuccessResult (count); }Alors, comment exporter? [En fait, on peut comprendre que l'exportation est l'affichage des données, mais le résultat n'est pas seulement JSON]
Si une question est soulevée, qu'en est-il de la connexion? Les solutions traditionnelles sont la déconnexion de connexion. Alors, quelle est l'idée de remplacer les ressources reposantes?
Astuce: la connexion est la nouvelle session. La déconnexion est la session de suppression.
accomplir
Sur la base des idées ci-dessus, nous pensions naturellement que nous n'avons besoin que de retourner plusieurs résultats à la même URL, n'est-ce pas correct? [PDF, une version, une version, une version, une version, une version, une version]]
Bingo! C'est l'origine du négociateur de contenu
Le négociateur de contenu n'a pas été créé par Spring, en fait, cela peut être vu à partir de l'en-tête HTTP.
1. Par exemple, le retour à la page anglais au client anglais est trop pour la page chinoise.
Le protocole HTTP définit les valeurs de qualité (appelées valeurs Q) qui permettent aux clients de répertorier plusieurs options pour chaque catégorie de préférence et d'associer une priorité pour chaque option de préférence.
Accept-Language: EN; Q = 0,5, Fr; Q = 0,0, NL; Q = 1,0, tr; Q = 0,0
Où la valeur Q varie de 0,0 à 1,0 (0,0 est la priorité la plus faible, tandis que 1,0 est la priorité la plus élevée).
Notez que l'ordre des préférences n'est pas important, seule la valeur Q liée aux préférences est importante
2. Ensuite, il y a d'autres paramètres tels que l'accept-tête
Habituellement, le négociateur de contenu a d'abord les solutions suivantes
1. Utilisez l'acceptation de l'en-tête:
Ceci est communément décrit dans les manuels. Idéalement, cette méthode est la meilleure, mais si vos ressources doivent être accessibles directement via le navigateur (c'est-à-dire l'affichage HTML), alors en raison des différences de navigateur, l'en-tête d'accepter envoyé sera différente. Cela amènera le serveur à ne pas savoir quel format de données vous retournera. Ce qui suit est l'en-tête d'accepter du navigateur
Chrome: accepter: application / xml, application / xhtml + xml, textml; q = 0,9, texte / plaine; q = 0,8, image / png, * / *; q = 0,5 Firefox: accepter: text / html, application / xhtml + xml, application / xml; q = 0,9, * / *; q = 0.8 ie8: accepter: image / goad / jpeg, image / jpeg, image, *; 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. Utilisez l'extension
La même URL a été perdue, mais cette méthode est le plus utilisée dans l'environnement réel car il est plus conforme à la vision esthétique des programmeurs.
Par exemple /user.json /user.xls /user.xml
En utilisant les paramètres maintenant de nombreuses API ouvertes utilisent cette méthode, comme Taobao
Cependant, pour différents navigateurs, l'accept-tête peut ne pas être particulièrement unifié, de nombreuses implémentations choisissent 2 3 deux solutions.
Nous adoptons les deux solutions ci-dessus au printemps
Configurez d'abord le négociateur de contenu
Code
@Bean Public ViewResolver ContentNegotitingViewResolver (contenuNegotiationManager Manager) {// Définissez la vue Resolvers ViewResolver BeanNameViewResolver = new BeanNameViewResolver (); List <ffewResolver> résolvers = listS.NewArrayList (beannameViewResolver); ContentNegotitingViewResolver Resolver = new ContentNegotitingViewResolver (); résolver.setViewResolvers (Resolvers); résolver.setContentNegotiationManager (directeur); RETOUR RESOLVER; } @Override public void configureContentNegotiation (contenuNegotiationConfigurer configure) {configurer.favarpathextension (true) .UseJaf (false) .favarParameter (true) .Parametername ("format") .IgNOreAccepcePtheDer (true) .DefaultContentType (MediaTyPe.Application_Jon). .MediaType ("JSON", mediatype.application_json) .MediaType ("xls", excel_media_type); }Créer le convertisseur correspondant
HttpMessageConverter privé <objet> createExcelHttpMessageConverter () {excelHttpMessageConverter ExcelHttpMessageConverter = new ExcelHttpMessageConverter (); return ExcelHttpMessageConverter; }Exporter les données directement à l'aide d'Easy-POI
/ * * Copyright (C) 2017. Lorem ipsum Dolor Sit Amet, cohetur adipiscing elit. * Morbi non Lorem Porttter 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. Pelletesque Sagittis Ligula Eget Metus. * Commodo vestibulaire. Ut Rhoncus Gravida Arcu. * / package com.f6car.base.web.converter; import Cn.Afterturn.Easypoi.excel.ExcelExportUtil; import com.f6car.base.common.result; Importer com.f6car.base.core.ExcelExport; import com.f6car.base.core.excexportParam; 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.generrichttpMessageConverter; import org.springframework.http.converter.httpMessageNotReadableException; import org.springframework.http.converter.httpMessagenotWitableException; Importer java.io.ioException; import java.lang.reflect.type; import java.net.urlencoder; import java.util.collection; Importer java.util.collections; Importer java.util.collections; importation java.util.map; import static com.f6car.base.core.f6static.getExcelExportParam; / ** * @author qixiaobo * / classe publique ExcelHttpMessageConverter étend AbstractThTTPMessageConverter <objet> implémente générichttpmessageConverter <objet> {public static final mediatype excel_media_type = new mediatype ("application", "vnd.ms-excel"); public excelHttpMessageConverter () {super (excel_media_type); } @Override Protected booléen supports (class <?> Clazz) {return false; } @Override Protected Object ReadInternal (class <?> Clazz, httpinputMessage inputMessage) lève ioException, httpMessageNotReadableException {return null; } @Override Protected void writeInternal (objet O, httpOutputMessage OutputMessage) lève ioException, httpMessageNotWitableException {httpheaders en-têtes = outputMessage.GetHeaders (); Données de collecte = getactualData ((résultat) o); ExceLexportParam ExceLexportParam = GetExceLexportParam (); Classeur de travail; switch (excelexportparam.getExcelExport ()) {case normalexcel: workbook = excelexportUtil.exportexcel (excexportparam.getExportParams (), (classe <?>) excexportParam.getClazz (), (collection <?>) data); casser; Case MapExcel: Workbook = ExceLexportUtil.ExportsExcel (ExcelexportParam.getExportParams (), ExceLexportParam.getExcelExportentitités (), (collection <? étend la carte <?,? >>)); casser; 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 ("attachement", codFileName); } workbook.write (outputMessage.getBody ()); }} Collection privée getactualData (résultat r) {if (r! = null && r.getData ()! = null) {objet 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 Collection.EmptyList (); } @Override public boolean canread (type type, classe <?> ContextClass, mediaType mediaType) {// excel return false n'est pas pris en charge; } @Override Public Object Read (Type Type, class <?> ContextClass, httpinputMessage inputMessage) lève ioException, httpMessageNotReadableException {return null; } @Override public boolean canwrite (type type, classe <?> Clazz, mediaType mediaType) {return super.canwrite (mediaType) && cllazz == 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 () + "pas supporter maintenant!"); retourne false; }} @Override public void write (objet O, type Type, MediaType ContentType, httpOutputMessage OutputMessage) lève ioException, httpMessagenotWitableException {super.write (o, contenuType, outputMessage); }}Pour le moment, c'est uniquement pour l'exportation, donc lorsqu'il est utilisé comme suit
@GetMapping @APioperation (value = "Get Entity List", Notes = "") Public Result List (S SO) {PageHelper.StartPage (so.getCurrentPage (), so.getPageSize ()); List <v> list = service.findall (); PageInfo pageInfo = new PageInfo (liste); ExceLexportParam (); return resultGenerator.GenSuccressResult (pageInfo); } protégé void excelexportParam () {exportParams ep = new exportParams (null, "data"); ExceLexportParam <v> param = new ExceLexportParam <> (); Param.SetClazz (Voclazz); param.setExcelExport (excelexport.normalexcel); param.setExportParams (EP); param.setFileName ("file.xls"); F6Static.sexcelExportParam (param); }Quand nous visitons
http://127.0.0.1:8079/zeus/user
{"Code": 200, "Data": {"Endrow": 10, "FirstPage": 1, "HasnextPage": True, "HaspreviousPage": false, "isFirstpage": True, "Islastpage": False, "Lastpage": 8, "List": [{"cellule": "13857445502", "IDEMPLOYE" 2420188343435260 "", "mot de passe": "96e79218965eb72c92a549dd5a330112", "pkid": 23993199378825296, "nom d'utilisateur": "Lingweiqiche"}, {"cellulephone": "," idemloyee ": 0" 4, "idWxbStation": "", "", "idWxbUser": "", "isAdmin": 0, "isDel": 0, "isGuideOpen": 0, "limitMac": 0, "openid": "", "password": "96e79218965eb72c92a549dd5a330112", "pkId": 24201883434356532, "Nom d'utilisateur": "007"}, {"téléphone portable": "15715139000", "idemployee": 24351585207523460, "idownorg": 24201883434357600, "idrole": 89, "idwxbsta "idWxbUser": "298", "isAdmin": 1, "isDel": 0, "isGuideOpen": 0, "limitMac": 0, "openid": "", "password": "96e79218965eb72c92a549dd5a330112", "pkId": 24201883434357600, "Nom d'utilisateur": "15715139000"}, {"portable": "", "idemployee": 0, "idownorg": 24201883434357600, "idrole": 216, "idwxbstation": "," idwxbuser ":", "Isadmin": 0, "Isdel": 0, "isUide" 0, "limitmac": 0, "openId": "", "mot de passe": "96e79218965eb72c92a549dd5a330112", "pkid": 24201883434357920, "username": "Sunlingli"}, {"cellphone": "" "" 24351585207425676, "idownorg": 24201883434359384, "idrole": 90, "idwxbstation": "348", "idwxbuser": "227", "Isadmin": 1, "Isdel": "ISGUIDEOPEN": 0, "Limite": 0, ":" ISGUIDEOPEN ": 0," "opzUDs_v13WE500kxYMj6Xg_gFeE", "password": "96e79218965eb72c92a549dd5a330112", "pkId": 24201883434359388, "username": "15952920979" }, { "cellPhone": "", "idemployee": 0, "idownorg": 24201883434359790, "idrole": 91, "idwxbstation": "315", "idwxbuser": "175" "96E79218965EB72C92A549DD5A330112", "PKID": 24201883434359790, "Nom d'utilisateur": "13809056211"}, {"Phone": "18903885585", "IDEMPLOYEE": 242018834343665 " "idownorg": 24201883434359890, "idrole": 92, "idwxbstation": "317", "idwxbuser": "178", "isadmin": 1, "isdel": 0, "isGuideOpen": 0, "limitemac": 0, "openID" "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": "," mot de passe ":: "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": "", "mot de passe": "96e79218965eb72c92a549dd5aa118965eb72c92a549d5aaa118965eb72c92a549d5aaa118965eb72c92a549d5aaaa1218965eb72c92a549d5aaaa118965eb72c92a549d5aaaa118965eb72c92a549d5aaaa1218965eb72c92a549d5aaAa "PKID": 24201883434360052, "nom d'utilisateur": "15221250005"}, {"portable": "", "idemployee": 0, "idownorg": 24201883434360070, "idrole": 95, "idwxbstation": "325", "idwxbuser," 198 "": "325", "idwxbuser," 198 "": "325", "idwxbuser," 198 "": "325", "idwxbuser," 198 "": "325", "idwxB "Isadmin": 1, "Isdel": 0, "isGuideopen": 0, "limitmac": 0, "openId": "", "mot de passe": "96e79218965eb72c92a549dd5a330112", "pkid": 24201883434360070, "Username": "13837251167070," Username ":" 13837251167070, " }], "navigationfirstpage": 1, "navigatelastpage": 8, "navigationpages": 8, "navigationpagenenums": [1, 2, 3, 4, 5, 6, 7, 8], "nextpage": 2, "commanderby": "", "pagenenum": ",": 10 " "Startrow": 1, "Total": 1012}, "Message": "Success"}Lorsque vous accédez à http://127.0.0.1:8079/zeus/user?format=xls ou http://127.0.0.1:8079/zeus/user.xls
Les effets suivants
Étant donné que les données ici sont liées à la requête, nous pouvons fonctionner de cette façon http://127.0.0.1:8079/zeus/user.xls?pageSize=1000 réalisez facilement XLSization des résultats de la requête!
Résumer
Ce qui précède est une illustration du négociateur de contenu dans Springboot présenté par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!