关于使用java Optional遇到的一些问题

来源:互联网 发布:音效下载软件 编辑:程序博客网 时间:2024/05/18 09:03

关于使用java Optional遇到的一些问题


这里写图片描述

case1.

以电子盘模块为例,在对接服务端后,controller返回json到前端的数据前台传入contronl的optional能正常接收,但是查询时却无法正确解析返回的Optional类型的数据类型,直接获取json中其中一个Entity.name,结果显示Obejct
这里写图片描述

thinking:


1、前端new一个domain实体,把Option类型的改成对应的非Optional类型
2、soa提供DzpList和DzpNoOptional,借用工具类生成,前端使用DzpNoOptional类型的list接受,接着遍历list数据并把EtradeList类型逐一转成DzpNoOptional,再add到DzpNoOptional类型的list返回json到前端。
3、抽取一个工具类方法,用于遍历处理步骤2在每个方法中都重复进行的操作。
4、在pagingBean的json数据返回前端的一些列数据转换过程中下手,关键在于该在什么处理方法中找到切入点。

Created with Raphaël 2.1.0Soa—List(TDzpSpecial)Soa—List(TDzpSpecial)Admin—List(TDzpSpecial)Admin—List(TDzpSpecial)List(TDzpSpecialNoOptional)List(TDzpSpecialNoOptional)js(json接收)js(json接收)调用soa返回数据集合遍历转换List集合TDzpSpecialpagingBean.getRows

extra1:方法2的处理方式:

案例

@RequestMapping(value = "querySpecials", method = RequestMethod.GET)@ResponseBodypublic KsPagingBean<TDzpSpecialNoOptional, TDzpSpecialNoOptional> querySpecials(QuerySpecialRequestNoOptional querySpecialRequestNoOptional, KsPagingBean<TDzpSpecialNoOptional, TDzpSpecialNoOptional> pagingBean) throws Exception {    DzpServiceClient dzpBidService = new DzpServiceClient();QuerySpecialRequest querySpecialRequest=ThriftBeanConverter.copy(querySpecialRequestNoOptional, QuerySpecialRequest.class);QuerySpecialResponse specialList = dzpBidService.getDzpSpecial(querySpecialRequest);List<TDzpSpecialNoOptional> specialNoOptionals = new ArrayList<>();/*    if (!CollectionUtils.isEmpty(specialList.getSpecial())) {for (TDzpSpecial special: specialList.getSpecial()) {            TDzpSpecialNoOptional specialNoOptional = TDzpSpecialNoOptional.copy(special);specialNoOptionals.add(specialNoOptional);}    }    pagingBean.setResults(specialList.getPageResponse().get().getResults());*/pagingBean.setRows(specialShowNoOptionals);    return pagingBean;}

extra2:方法4的处理方式:

a、引入jackson升级包

        <!-- Jackson JSON Processor使用2.6.3。jdk8Module -->        <dependency>            <groupId>com.fasterxml.jackson.datatype</groupId>            <artifactId>jackson-datatype-jdk8</artifactId>            <version>${com.fasterxml.jackson.version}</version>        </dependency>        <dependency>            <groupId>com.fasterxml.jackson.core</groupId>            <artifactId>jackson-databind</artifactId>            <version>${com.fasterxml.jackson.version}</version>        </dependency>

b、jackson2.6.3成功解析option的原因

       //Jdk8Module        context.addSerializers(new Jdk8Serializers());        context.addDeserializers(new Jdk8Deserializers());        context.addTypeModifier(new Jdk8TypeModifier());        //com.fasterxml.jackson.datatype.jdk8        //Jdk8Serializers        //OptionalSerializer         public void serialize(Optional<?> opt, JsonGenerator gen, SerializerProvider provider) throws IOException {        if(opt.isPresent()) {            Object value = opt.get();            JsonSerializer ser = this._valueSerializer;            if(ser == null) {                ser = this._findCachedSerializer(provider, value.getClass());            }            ser.serialize(value, gen, provider);        } else {            provider.defaultSerializeNull(gen);        }

case2.

以网站部分同样对于Optional类型的返回不友好场景分两种

1. responseBody返回json数据到js中
2. request.setAttribute(“pageResponse”, response)返回数据到jsp中,jsp通过c:forEach、c:out标签遍历显示数据

extra1:对于场景1的mind

案例:

@RequestMapping(value = "listtest", method = RequestMethod.GET)@ResponseBodypublic void listtest(PagingBean<Person> pb, Person claim,HttpServletResponse response) {        List<Person> personList=new ArrayList<Person>();Person person1=new Person();Person person2=new Person();person1.setName(Optional.of("luosan"));person1.setHobby("乒乓球");person1.setId(1);person2.setName(Optional.of("lufei"));person2.setHobby("白云机场");person2.setId(2);personList.add(person1);personList.add(person2);pb.setRows(personList);HttpServletHelper.writeJsonToResponse(response, pb);}

thinking:

1、对于现有HttpServletHelper的json处理方式改装

try {  //原有方式   response.getWriter().print(new Gson().toJson(responseData));  //改装方式   ObjectMapper mapper = new ObjectMapper();mapper.registerModule(new Jdk8Module());String withEmailJson = mapper.writeValueAsString(responseData);response.getWriter().print(withEmailJson);} catch (IOException e) {LOGGER.error(e.getMessage(), e);}

2、对于每次Registering module需要重新封装
3、在其他的返回数据处理层进行处理?

extra2:对于场景2的mind

这里写图片描述

thinking

因为jsp中的jstl标签直接对java中的对象操作,所以这个时候并未在返回jsp的过程中进行json序列化之类的处理,可以理解为此时的对象与control层的对象基本一致。
问题在于c:out标签解析的时候不支持optional的类型,效果如上图
于是我试图通过更改jstl标签实现支持


package org.apache.taglibs.standard.tag.el.core;public class OutTag extends OutSupport {    // Accessors    // for tag attributepublic void setValue(Object value) {      //原有方式       this.value =value       //改装方式       this.value =value instanceof Optional? ((Optional) value).get():value;}public void setDefault(String def) {this.def = def;}public void setEscapeXml(boolean escapeXml) {this.escapeXml = escapeXml;}}

2、改写OutTag 是应该自定义标签呢还是直接改写标签?,是否有其他更好的方式在jsp获取数据时候进行一次处理呢?
3、对于partner对Optional[lufei222]进行字符串截取是否可行?

这里写图片描述


参考文献:

  1. https://github.com/FasterXML/jackson-datatype-jdk8
  2. http://stackoverflow.com/questions/31543756/spring-mvc-requestbody-map-optionalenum/31556073#31556073
  3. http://www.cnblogs.com/davidwang456/p/4257001.html
0 0
原创粉丝点击