栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot中的内容协商器图解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot中的内容协商器图解

背景

使用了restful的小伙伴对于导出这些需求本能就是拒绝的~破坏了restful的url的一致性【严格矫正 不是http json就是restful 很多小伙伴都会吧暴露出一个json就直接称为restful 】

正如上文的代码生成器 我们会批量生成一堆代码 其中绝大部分都是RestController

  public abstract class AbstractRestController {
    protected Class voClazz;
    @Autowired
    private Service service;
    public AbstractRestController() {
      TypeToken voType = new TypeToken(getClass()) {
      };
      voClazz = (Class) voType.getRawType();
    }
    @PostMapping()
    @ApiOperation(value = "新建实体", notes = "")
    public Result add(@RequestBody V vo) {
      service.saveSelective(vo);
      return ResultGenerator.genSuccessResult();
    }
    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除实体", notes = "")
    public Result delete(@PathVariable PK id) {
      service.deleteById(id);
      return ResultGenerator.genSuccessResult();
    }
    @PutMapping
    @ApiOperation(value = "更新实体", notes = "")
    public Result update(@RequestBody V vo) {
      service.updateByPrimaryKeySelective(vo);
      return ResultGenerator.genSuccessResult();
    }
    @GetMapping
    @ApiOperation(value = "获取实体列表", notes = "")
    public Result list(S so) {
      PageHelper.startPage(so.getCurrentPage(), so.getPageSize());
      List list = service.findAll();
      PageInfo pageInfo = new PageInfo(list);
      excelExportParam();
      return ResultGenerator.genSuccessResult(pageInfo);
    }
    protected void excelExportParam() {
      ExportParams ep = new ExportParams(null, "数据");
      ExcelExportParam param = new ExcelExportParam<>();
      param.setClazz(voClazz);
      param.setExcelExport(ExcelExport.NormalExcel);
      param.setExportParams(ep);
      param.setFileName("文件.xls");
      F6Static.setExcelExportParam(param);
    }
    @GetMapping("/{id}")
    @ApiOperation(value = "获取单个实体", notes = "")
    public Result detail(@PathVariable PK id) {
      V vo = service.findById(id);
      return ResultGenerator.genSuccessResult(vo);
    }
    @DeleteMapping("/batch")
    @ApiOperation(value = "批量删除实体", notes = "")
    public Result batchDelete(@RequestParam String ids) {
      service.deleteByIds(ids);
      return ResultGenerator.genSuccessResult();
    }
    @GetMapping("/batch")
    @ApiOperation(value = "批量获取实体", notes = "")
    public Result batchDetail(@RequestParam String ids) {
      List vos = service.findByIds(ids);
      return ResultGenerator.genSuccessResult(vos);
    }
    @PostMapping("/batch")
    @ApiOperation(value = "批量新建实体", notes = "")
    public Result add(@RequestBody List vos) {
      service.save(vos);
      return ResultGenerator.genSuccessResult();
    }
    @GetMapping("/count")
    @ApiOperation(value = "获取实体数目", notes = "")
    public Result count(@RequestBody V v) {
      int count = service.selectCount(v);
      return ResultGenerator.genSuccessResult(count);
    }

那么导出如何做呢?【其实可以理解成导出就是数据的展示 不过此时结果不是json而已】

抛出一个问题那么登录登出呢?传统的方案都是login logout 那么换成restful资源的思路是啥呢?

提示: 登录就是session的新建 登出就是session的删除

实现

基于上述思路 我们自然就想到了那么我们只需要对同一个url返回多种结果不就OK了?【pdf一个版本 json一个版本 xml一个版本 xls一个版本】

bingo!这个是内容协商器的由来

内容协商器并不是Spring创造出来的 事实上这个从http头里面也能看出

1.比如给英语客户返回英语页面 过于客户返回汉语页面

HTTP 协议中定义了质量值(简称 q 值),允许客户端为每种偏好类别列出多种选项,并为每种偏好选项关联一个优先次序。

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 是优先级最低的,而 1.0 是优先级最高的)。

注意,偏好的排列顺序并不重要,只有与偏好相关的 q 值才是重要的

2.那么还有其他的一些参数 比如 accept-header

通常是先内容协商器有如下几种方案

1.使用Accept header:

这一种为教科书中通常描述的一种,理想中这种方式也是最好的,但如果你的资源要给用户直接通过浏览器访问(即html展现),那么由于浏览器的差异,发送上来的Accept Header头将是不一样的. 将导致服务器不知要返回什么格式的数据给你. 下面是浏览器的Accept Header   

 chrome: 
    Accept:application/xml,application/xhtml+xml,textml;q=0.9,text/plain;q=0.8,image/png,**;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, *
  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;
  
  public class ExcelHttpMessageConverter extends AbstractHttpMessageConverter
      implements GenericHttpMessageConverter {
    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>) 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);
    }
  }

暂时只是针对导出 因此在使用的时候如下

 @GetMapping
  @ApiOperation(value = "获取实体列表", notes = "")
  public Result list(S so) {
    PageHelper.startPage(so.getCurrentPage(), so.getPageSize());
    List list = service.findAll();
    PageInfo pageInfo = new PageInfo(list);
    excelExportParam();
    return ResultGenerator.genSuccessResult(pageInfo);
  }
  protected void excelExportParam() {
    ExportParams ep = new ExportParams(null, "数据");
    ExcelExportParam param = new ExcelExportParam<>();
    param.setClazz(voClazz);
    param.setExcelExport(ExcelExport.NormalExcel);
    param.setExportParams(ep);
    param.setFileName("文件.xls");
    F6Static.setExcelExportParam(param);
  }

当我们访问时如下

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": [
  {
  "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"
  }

当访问http://127.0.0.1:8079/zeus/user?format=xls 或者http://127.0.0.1:8079/zeus/user.xls

如下效果

由于这边的数据和查询有关 因此我们可以这样操作http://127.0.0.1:8079/zeus/user.xls?pageSize=1000 轻而易举实现了查询结果xls化!

总结

以上所述是小编给大家介绍的SpringBoot中的内容协商器图解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号