美文网首页码农的世界程序员技术栈
前台请求遍历java枚举,枚举多个属性,js插件接收

前台请求遍历java枚举,枚举多个属性,js插件接收

作者: 刘振宁的博客 | 来源:发表于2019-03-15 16:43 被阅读22次

    巨大的建筑,总是由一木一石叠起来的,我们何妨做做这一木一石呢?我时常做些零碎事,就是为此。
    这是对的,但是我没有说过这句话! —— 鲁迅

    在java中,对于一些字典项,可以用枚举表示,比如有多少种类型的车品牌等。
    在前端,需要一个下拉框来表示这些车牌,如果在前台设置这些值的话,相当于同一件事干了两次。
    这里就打算直接请求后端,返回枚举的列表。

    多个属性的枚举

    枚举是可以有自己的属性的,这里用 车辆品牌来举例,truckBrand

    package com.enn.zhwl.commons.enums;
    
    import java.io.Serializable;
    
    public enum TruckBrand implements Serializable {
      DONGFENG("dongfeng", "东风", "DFYT", FuelType.OILHEAD),
      JIEFANG("jiefang", "解放", "JF", FuelType.GASHEAD),
      OUMAN("ouman", "欧曼", "FTOM", FuelType.OILHEAD),
      SITANNIYA("sitanniya", "斯坦尼亚", "SCANIA", FuelType.OILHEAD),
      DONGFENGTIANLONG("dongfengtianlong", "东风天龙", "DFTL", FuelType.GASHEAD),
      HUALING("hualing", "华菱", "HLYT", FuelType.OILHEAD),
      HUALINGLNG("hualinglng", "华凌LNG", "HLQT", FuelType.GASHEAD),
      //新增 @2019/03/14
      HUALINGHANMA("hualinghanma","华菱悍马", "HLHM", FuelType.GASHEAD),
      SHENGDAYIN("shengdayin", "圣达因", "SHDY", FuelType.OILHEAD),
      UD("ud", "UD", "UD", FuelType.OILHEAD);
    
      TruckBrand(String value, String desc, String diaoDuName, FuelType fuelType) {
        this.value = value;
        this.desc = desc;
        this.diaoDuName = diaoDuName;
        this.fuelType = fuelType;
      }
    
      private String value;
      private String desc;
      //对应调度平台的名称.
      private String diaoDuName;
      //该品牌车的燃料类型.
      private FuelType fuelType;
    
      public String getDiaoDuName() {
        return diaoDuName;
      }
    
      public FuelType getFuelType() {
        return fuelType;
      }
    
      public String getValue() {
        return value;
      }
    
      public String getDesc() {
        return desc;
      }
    
    
      @Override
      public String toString() {
        return new StringBuffer("{\"name\":\"").append(name())
            .append("\",\"value\":\"").append(value)
            .append("\", \"desc\":\"").append(desc)
            .append("\", \"diaoDuName\":\"").append(diaoDuName)
            .append("\", \"fuelType\":").append(fuelType)
            .append("}").toString();
      }
    }
    

    这个枚举有4个属性,value,desc,diaoDuName,fuelType.

    values()方法

    枚举中有一个很重要的方法是values()方法,他可以遍历枚举,返回枚举的列表。

    打印枚举的所有属性

    对于前台一般是使用JSON的,首先想到用JSON工具来转化一下,我这里用到的是fastJson,

    System.out.println(JSON.toJSONString(TruckBrand.DONGFENG));
    

    只打印出来 “DONGFENG”, 却没有相应的属性
    后来通过跟代码,发现对于枚举可以进行设置,是打印名字,还是打印toString方法.
    如下:

    System.out.println(JSON.toJSONString(TruckBrand.DONGFENG, SerializerFeature.WriteEnumUsingToString));
    

    当然,显示调用 toString方法也是可以的.

    json 中双引号,单引号的问题

    经过尝试,在json中假如使用单引号,或者无引号的话,是不能转换为JSON的,必须使用双引号才可以。


    image.png

    对于对象而言,不能使用双引号,不加引号就可以。这样才能把它当成一个对象来看待.加了引号会当成字符串来看待。


    image.png

    通过反射,来执行values方法

    因为这个问题比较共性,客户端只需要传输枚举的类名即可。
    假如通过 Class.forName()来获取的话,必须需要包路径,而枚举类的包路径不一定的固定的,这里直接使用map来保存相应的class.

      package com.enn.zhwl.api.common.system;
    
    import com.alibaba.fastjson.JSON;
    import com.enn.zhwl.commons.Result;
    import com.enn.zhwl.commons.ResultSet;
    import com.enn.zhwl.commons.State;
    import com.enn.zhwl.commons.enums.TruckBrand;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author liuzhenning
     * @version 0.0.1
     * @since 0.0.1 2019-03-14
     * 字典请求类.
     */
    @Controller
    @RequestMapping("/dic")
    public class DicApi {
    
      private Logger logger = LoggerFactory.getLogger(DicApi.class);
    
      private static Map<String, Class> enumMaps = new HashMap<String, Class>() {{
        put("truckBrand", TruckBrand.class);
      }};
    
      @RequestMapping(value = "/{enumName}", method = RequestMethod.GET)
      @ResponseBody
      public Result<Object, State> findDict(@PathVariable String enumName) {
        Result<Object, State> resultSet = new Result<>();
        try {
          if (enumMaps.containsKey(enumName)) {
            Class aClass = enumMaps.get(enumName);
            Method valuesMethod = aClass.getMethod("values");
            Object[] values = (Object[])valuesMethod.invoke(null);
            resultSet.setData(JSON.parseArray(Arrays.toString(values)));
            resultSet.setCode(State.SUCCESS);
          } else {
            resultSet.setCode(State.FAILED);
            resultSet.setMessage("key not exist");
          }
        } catch (Exception e) {
          e.printStackTrace();
          resultSet.setCode(State.FAILED);
          resultSet.setMessage(e.getMessage());
        }
        return resultSet;
      }
    
    }
    

    这里是显示的调用了toString方法,即 Arrays.toString(values),这样调用的。
    在返回到前台的时候,spring MVC在这里自动使用 fastJson转了一下,因为默认的是不用toString方法的,所以这里将相应的对象转化为字符串,再转化为对象
    (这里的对象就不是枚举了,而是JSONObject了),这样就能传回到前台了。

    前端js接收相应的返回值,构建成select下拉框.

      /***
     * @Author:liuzhenning
     * @function:直接从服务端获取Enum。
     * @Date: 2019-03-14
     * 直接调用makeHtml(enumName) enumName 为枚举类,如:truckBrand
     */
    
    (function (win,$) {
        /**
         * 对象.
         * @param enumName 枚举类
         * @param head 头一个要显示的,比如:品牌
         * @constructor
         */
        var Enum = function (enumName,head) {
            this.enumName = enumName;
            this.head = head;
            this.datas = '';
        }
    
        win.Enum = Enum;
    
        Enum.prototype.getEnum = function () {
            var me = this;
            var enumName = me.enumName;
            $.ajax({
                url:api_host + "dic/" + enumName,
                type:'get',
                async:false,
                dataType:'json',
                success:function (result) {
                    var code = result.code;
                    var data = result.data;
                    if (result.code == 'SUCCESS') {
                        me.datas = data;
                    }
                }
            })
        };
        Enum.prototype.makeHtml = function () {
            var me = this;
            var enumName = me.enumName;
            if (!me.datas) {
                me.getEnum(enumName);
            }
            var datas = me.datas;
            var $select = $('<select name="'+ enumName +'"></select>');
            var $head = $('<option value="">'+ me.head +'</option>');
            $select.append($head);
            for (var i=0;i<datas.length;i++) {
                var data = datas[i];
                var $option = $('<option value="'+ data.name +'">'+ data.desc +'</option>');
                $select.append($option);
            }
            return $select;
        };
        Enum.prototype.getDataItem = function (name) {
            var datas = this.datas;
            for (var i=0;i<datas.length;i++) {
                var temp = datas[i];
                if (name == temp.name) {
                    return temp;
                }
            }
            return null;
        }
    })(window,jQuery);
    

    代码见上面,稍微封装了一下,具体的做法,可以参考 https://www.jianshu.com/p/fa24f71be4e7
    调用如下:

    var truckBrandEnum = new Enum('truckBrand','品牌');
    var $select = truckBrandEnum.makeHtml();
    

    假如是品牌的话,只需要new一次就行了,假如再加另外一个,比如:性别,就再new一个.

    后记

    感觉java的枚举不好用,还不如直接将 这些字典 存到库中,建造一个字典类来处理,刚方便.

    相关文章

      网友评论

        本文标题:前台请求遍历java枚举,枚举多个属性,js插件接收

        本文链接:https://www.haomeiwen.com/subject/ukdrmqtx.html