fondo
Los amigos que usan un instinto RESTFUL para exportar estas necesidades se rechazan ~ destruye la consistencia de las URL de descanso [la corrección estricta es HTTP JSON o RESTFORM. Muchos amigos expondrán un JSON y lo llamarán RESTFOR directamente]
Como en el generador de código anterior, generaremos un montón de códigos, la mayoría de los cuales son RestControllers.
Public Abstract Class AbstracTrestController <V extiende VO, S extiende SO, PK extiende Serializable> {Clase protegida <v> Voclazz; @Autowired Service privado <V, S, PK> Servicio; public AbStrestController () {typeToken <V> votype = new typetoken <v> (getClass ()) {}; VOVLAZZ = (CLASE <V>) VOTYPE.GETRAWTYPE (); } @PostMapping () @apioperation (valor = "nueva entidad", notas = "") resultado público add (@RequestBody V Vo) {Service.SavesElective (Vo); return denteGenerator.GensuccessResult (); } @DeletEmapping ("/{id}") @apioperation (value = "Eliminar entidad", notas = "") Public Result Delete (@PathVariable PK ID) {Service.DeleteById (id); return denteGenerator.GensuccessResult (); } @Putmapping @apioperation (valor = "Entidad de actualización", notas = "") Actualización de resultados públicos (@RequestBody V Vo) {Service.UpdateByPrimaryKeySelective (Vo); return denteGenerator.GensuccessResult (); } @Getmapping @apioperation (value = "get entidad lista", notas = "") Lista de resultados públicos (s SO) {pageHelper.StartPage (So.getCurrentPage (), SO.getPageSize ()); List <v> list = Service.Findall (); PageInfo PageInfo = new PageInfo (lista); ExcelExportParam (); return denteGenerator.GensuccessResult (pageInfo); } protegido Void ExcelExportParam () {ExportParams EP = New ExportParams (nulo, "datos"); ExcelExportParam <V> param = new ExcelExportParam <> (); param.setClazz (Voclazz); param.setExcelExport (ExcelExport.normAxcel); param.setExportParams (EP); param.setFileName ("file.xls"); F6static.setExcelExportParam (param); } @Getmapping ("/{id}") @apioperation (valor = "obtener entidad única", notas = "") Detalle de resultado público (@PathVariable PK ID) {v Vo = Service.FindById (id); return denteGenerator.GensuccessResult (Vo); } @DeletEmapping ("/batch") @apioperation (value = "Batch Eliminar entidad", notas = "") Resultado público BatchDelete (@RequestParam String IDS) {Service.DeleteByIds (IDS); return denteGenerator.GensuccessResult (); } @Getmapping ("/batch") @apioperation (value = "batch get entity", notas = "") public dulte batchDetail (@RequestParam String ids) {list <v> vos = servicio.findbyids (IDS); return denteGenerator.GensuccessResult (VOS); } @PostMapping ("/batch") @apioperation (value = "batch nueva entidad", notas = "") resultado público add (@RequestBody List <V> Vos) {Service.Save (Vos); return denteGenerator.GensuccessResult (); } @Getmapping ("/count") @apioperation (value = "Obtener el número de entidades", notas = "") Conteo de resultados públicos (@RequestBody V V) {int count = Service.SelectCount (v); return denteGenerator.GensuccessResult (Count); }Entonces, ¿cómo exportar? [De hecho, se puede entender que la exportación es la visualización de datos, pero el resultado no es solo JSON]
Si se plantea una pregunta, ¿qué hay de iniciar sesión? Las soluciones tradicionales son el inicio de sesión de inicio de sesión. Entonces, ¿cuál es la idea de reemplazar los recursos reparadores?
Consejo: el inicio de sesión es la nueva sesión. El inicio de sesión es la sesión de eliminación.
lograr
Según las ideas anteriores, naturalmente pensamos que solo necesitamos devolver múltiples resultados a la misma URL, ¿no está bien? [PDF, una versión, una versión, una versión, una versión, una versión, una versión]
¡bingo! Este es el origen del negociador de contenido
El negociador de contenido no fue creado por Spring, de hecho, esto se puede ver desde el encabezado HTTP.
1. Por ejemplo, volver a la página inglesa al cliente inglés es demasiado para la página china.
El protocolo HTTP define los valores de calidad (denominados valores Q) que permiten a los clientes enumerar múltiples opciones para cada categoría de preferencia y asociar una prioridad para cada opción de preferencia.
Aceptar el idioma: EN; Q = 0.5, FR; Q = 0.0, NL; Q = 1.0, TR; Q = 0.0
Donde el valor Q varía de 0.0 a 1.0 (0.0 es la prioridad más baja, mientras que 1.0 es la prioridad más alta).
Tenga en cuenta que el orden de las preferencias no es importante, solo el valor de Q relacionado con las preferencias es importante
2. Luego hay algunos otros parámetros, como Accept-Header
Por lo general, el negociador de contenido primero tiene las siguientes soluciones
1.Use Aceptar encabezado:
Este es un comúnmente descrito en los libros de texto. Idealmente, este método es el mejor, pero si se accede directamente a sus recursos a través del navegador (es decir, pantalla HTML), entonces debido a las diferencias del navegador, el encabezado de aceptación enviado será diferente. Esto hará que el servidor no sepa qué formato de datos le devolverá. El siguiente es el encabezado de aceptación del navegador
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, Application/X-Shockwave-Flash, Application/X-Silverlight, Application/X-MS-Aplication, Application/X-MS-XBap, Application/VND.MS-XPSDocument, Application/Xaml+XML, */ *
2. Use la extensión
Se ha perdido la misma URL, pero este método se usa más en el entorno real porque está más en línea con la visión estética de los programadores.
Por ejemplo /user.json /user.xls /user.xml
Usando parámetros ahora muchas API abiertas usan este método, como Taobao
Sin embargo, para los diferentes navegadores, la aceptación de aceptación puede no estar particularmente unificada, por lo que muchas implementaciones eligen 2 3 dos soluciones.
Adoptamos las dos soluciones anteriores en primavera
Primero configure el negociador de contenido
Código
@Bean public ViewResolver ContentNegotiatingViewResolver (ContentNegotiationManager Manager) {// Defina los resueltos View ViewResolver BeanNameViewResolver = new BeanViewResolver (); List <ViewResolver> resolvers = lists.newArrayList (BeanNameViewResolver); ContentNegotiatingViewResolver Resolver = new ContentNegotiatingViewResolver (); resolver.setViewResolvers (resolvers); resolver.setContentNegotiationManager (gerente); Resolver de devolución; } @Override public void configureContentNegotiation (ContentNegotiationConfigurer configure) {configure.fateVePathExtension (true) .usejaf (false) .favorParameter (true) .parametername ("format") .InignReAcPEpTheader (true) .DefaultcontentTypeTypeType (mediAtype.applicationationse_json. Mediatype.application_json) .mediatype ("xls", Excel_media_Type); }Crear el convertidor correspondiente
Private httpMessageConverter <ject> createExcelhttpMessageConverter () {ExcelhttpMessageConverter ExcelhttpMessageConverter = new ExcelhttpMessageConverter (); devolver ExcelhttpMessageConverter; }Exportar datos directamente utilizando Easy-Poi
/ * * Copyright (c) 2017. Lorem ipsum dolor Sit amet, consistente 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. * Comrodo vestibular. UT Rhoncus gravida Arcu. */ paquete 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; importar org.apache.poi.ss.usermodel.workbook; importar org.springframework.http.httpheaders; importar org.springframework.http.httpinputMessage; importar org.springframework.http.httpoutputMessage; importar org.springframework.http.mediatype; importar org.springframework.http.converter.abstractthttpMessageConverter; importar org.springframework.http.converter.generichttpMessageConverter; importar org.springframework.http.converter.httpmessageTreadableException; importar 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.collections; import java.util.map; import static com.f6car.base.core.f6static.getExcelExportParam; / ** * @author qixiaobo */ public class ExcelhttpMessageConverter extiende AbstracthttpMessageConverter <ject> implementa generichttpmessageConverter <pectus> {public static final mediatype Excel_media_type = new Mediatype ("aplicación", "vnd.ms-xcel"); public ExcelhttpMessageConverter () {super (Excel_Media_Type); } @Override protegidos boolean soports (class <?> Clazz) {return false; } @Override Object Protected ReadInternal (clase <?> Clazz, httpinputMessage inputMessage) lanza ioexception, httpMessageNotreadableException {return null; } @Override void writeinternal (objeto O, httpoutputMessage outputMessage) lanza ioexception, httpMessagenotwritableException {httpheaders encabezados = outputMessage.Getheaders (); Datos de recopilación = getActualData ((resultado) o); ExcelExportParam ExcelExportParam = getExcelExportParam (); Libro de trabajo de trabajo; switch (ExcelExportParam.getExcelExport ()) {case normalexcel: workbook = ExcelexportUtil.ExportExcel (ExcelExportParam.GetExportParams (), (clase <?>) ExcelexportParam.getClazz (), (recopilación <?>) datos); romper; Case Mapexcel: Workbook = ExcelExportUtil.ExportExcel (ExcelExportParam.GetExportParams (), ExcelExportParam.GetExcelExportentities (), (Collection <? Extends Map <?,? >>) datos); romper; Case BigExcel: Case MapexCelgraph: Case PDFTMPLATE: Case TemplateExcel: Case Templateword: Predeterminado: tirar nueva runtimeException (); } if (Workbook! = NULL) {if (ExcelExportParam.getFileName ()! = NULL) {String codedFileName = urlencoder.Encode (ExcelExportParam.getFileName (), "UTF8"); Headers.setContentDIsPositionFormData ("Adjunto", CodedFileName); } Workbook.Write (outputMessage.getBody ()); }} colección privada getActualData (resultado r) {if (r! = null && r.getData ()! = null) {objeto data = r.getData (); if (data instanceOf pageInfo) {return ((pageInfo) data) .getList (); } else if (! (data instanciaf colección)) {data = lists.newarrayList (datos); } else {return (colección) datos; }} return Collections.emptylist (); } @Override public boolean Canread (tipo tipo, clase <?> ContextClass, mediatype Mediatype) {// Excel return false no es compatible; } @Override Public Object Read (tipo tipo, clase <?> ContextClass, httpinputMessage inputMessage) lanza ioexception, httpMessageNotreadableException {return null; } @Override public boolean CanWrite (tipo tipo, clase <?> Clazz, Mediatype Mediatype) {return super.canwrite (mediatype) && clazz == result.class && support (); } soporte booleano privado () {ExcelExportParam param = getExcelExportParam (); if (param == null || param.getExcelExport () == null || param.getExportParams () == null) {return false; } if (param.getExcelExport () == ExcelExport.normAxcel) {return true; } else {logger.warn (param.getExcelExport () + "¡No es compatible ahora!"); devolver falso; }} @Override public void Write (objeto o, tipo de tipo, mediatype contentType, httpoutputMessage outputMessage) lanza ioexception, httpmessagenotwritableException {super.write (o, contentType, outputMessage); }}Por el momento, es solo para la exportación, por lo que cuando se usa de la siguiente manera
@Getmapping @apioperation (valor = "get entidad lista", notas = "") Lista de resultados públicos (s SO) {pageHelper.StartPage (SO.GetCurrentPage (), SO.getPageSize ()); List <v> list = Service.Findall (); PageInfo PageInfo = new PageInfo (lista); ExcelExportParam (); return denteGenerator.GensuccessResult (pageInfo); } protegido Void ExcelExportParam () {ExportParams EP = New ExportParams (nulo, "datos"); ExcelExportParam <V> param = new ExcelExportParam <> (); param.setClazz (Voclazz); param.setExcelExport (ExcelExport.normAxcel); param.setExportParams (EP); param.setFileName ("file.xls"); F6static.setExcelExportParam (param); }Cuando visitamos
http://127.0.0.1:8079/zeus/user
{"Código": 200, "Data": {"Endrow": 10, "FirstPage": 1, "HasnextPage": True, "HaspreviousPage": false, "isFirstPage": true, "islastPage": false, "LastPage": 8, "List": ["Cellphone": "13857445502", "Idemapee": "" Idemapleee ":" Idemapleee: "Idemaplete:" Idemaplete: "Idemaplete:" Idemaplete: "Idemaplete:" Idemaply: "Idemapleee:" Idemaplete: ":" Idemaplete: "IdemapladE. 24201883434352650, "Idownorg": 23993199378825296, "iDrole": 88, "idwxbstation": "332", "idwxbuser": "207", "isadmin": 1, "isDel": 0, "isguideopen": 0, ",", ",", 0, ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",". "", "contraseña": "96e79218965eb72c92a549dd5a330112", "pkid": 23993199378825296, "username": "lingweiqiche"}, {"teléfono celular": "", "ideemploye": 0, "iownorg": 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999. 4, "idWxbStation": "", "", "idWxbUser": "", "isAdmin": 0, "isDel": 0, "isGuideOpen": 0, "limitMac": 0, "openid": "", "password": "96e79218965eb72c92a549dd5a330112", "pkId": 24201883434356532, "Nombre de usuario": "007"}, {"celular": "15715139000", "ideMployee": 24351585207523460, "Idownorg": 24201883434357600, "iDrole": 89, 89, "Idwxbstation", "540 540" 5440 "," 5440 "," 5440 ". "IDWXBUSER": "298", "isadmin": 1, "isDel": 0, "isGideOpen": 0, "LimitMac": 0, "OpenId": "," Contraseña ":" 96E79218965EB72C92A549DDDD5A330112 "," PKID ": 2420183434343577400 "Nombre de usuario": "15715139000"}, {"teléfono celular": "", "ideMployee": 0, "Idownorg": 24201883434357600, "iDrole": 216, "Idwxbstation": "," IdWxBuser ":", "isAdmin": 0, ISDEL ": 0,", "," es "," está ":" ISUDE ":" ISGUIDE ":" ISGUIDE ":" ISGUIDE ":" ISGUIDE ":" ISGUIDE ":" ISGUIDE ":" ISGUIDE ": ISGUID 0, "LimitMac": 0, "OpenId": "", "Contraseña": "96E79218965EB72C92A549DDD5A330112", "PKID": 24201883434357920, "UserName": "Sunli"}, {"Celular de la celda": "", "," "," "," "," "," "Idemleado" 24351585207425676, "idownorg": 24201883434359384, "iDrole": 90, "idwxbstation": "348", "idwxbuser": "227", "isadmin": 1, "isDel": 0, "isguideopen": 0, "LimitMac": 0, 0, 0, ", 0,", ": 0, 0,", ",", ", 0,", ",", ",", ",", ",", ",", ",", ",", ",", ",", ",", "Limitid": "Limitid": "Limitid" "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, "abreID": "," ":": ":": ":" "96e79218965eb72c92a549dd5a330112", "pkid": 2420183434359790, "nombre de usuario": "13809056211"}, {"teléfono celular": "18903855585", "ideemploye": 242018888834 "Idownorg": 24201883434359890, "iDrole": 92, "IdwxbStation": "317", "idwxbuser": "178", "isadmin": 1, "isdel": 0, "isguideopen": 0, "limitMac": 0, "abierto": "," contraseña ":" contraseña " "96e79218965eb72c92a549dd5a330112", "pkId": 24201883434359892, "username": "18903885585" }, { "cellPhone": "", "idEmployee": 24351585207425668, "idOwnOrg": 242018834343599924, "Idrole": 93, "IdwxbStation": "318", "Idwxbuser": "179", "isadmin": 1, "isDel": 0, "isguideopen": 0, "limitmac": 0, "openId": ":" PASSINA "96e79218965eb72c92a549dd5a330112", "pkid": 242018343434359930, "nombre de usuario": "133722299595"}, {"teléfono celular": "", "ideMployee": 0, "iownorg": 242018888883434 "Idrole": 94, "IdwxbStation": "321", "idwxbuser": "188", "isadmin": 1, "isDel": 0, "isguideopen": 0, "limitMac": 0, "openid": "," contraseña ":" 96e79218965eb72c92a54912 ", "pkId": 24201883434360052, "username": "15221250005" }, { "cellPhone": "", "idEmployee": 0, "idOwnOrg": 24201883434360070, "idRole": 95, "idWxbStation": "325", "idWxbUser": "198", "isadmin": 1, "isdel": 0, "isGuideOpen": 0, "LimitMac": 0, "OpenId": "", "Contraseña": "96E79218965EB72C92A549DDDDD5A330112", "PKID": 2420183343360070, "UsseSeNeName" 13833721111111111111111111111111111111672172167 "". }], "navegateFirstPage": 1, "NavigatelastPage": 8, "NavigatePages": 8, "NavigatePageNums": [1, 2, 3, 4, 5, 6, 7, 8], "NextPage": 2, "Orderby": "", "Pagenum": 1, "PageSize": 10, "Page": 102, 102, "," Tamaño ":" Tampo ":" Tampo " 10, "Startrow": 1, "Total": 1012}, "Mensaje": "Suciedad"}Al acceder a http://127.0.0.1:8079/zeus/user?format=xls o http://127.0.0.1:8079/zeus/user.xls
Los siguientes efectos
Dado que los datos aquí están relacionados con la consulta, podemos operar de esta manera http://127.0.0.1:8079/zeus/user.xls?pagesize=1000 ¡Fácilmente realización de la xlsización de los resultados de la consulta!
Resumir
Lo anterior es una ilustración del negociador de contenido en Springboot presentada por el editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!