前臺請求遍歷java枚舉,枚舉多個屬性,js插件接收

巨大的建築,總是由一木一石疊起來的,我們何妨做做這一木一石呢?我時常做些零碎事,就是爲此。
這是對的,但是我沒有說過這句話! —— 魯迅

在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的,必須使用雙引號纔可以。


對於對象而言,不能使用雙引號,不加引號就可以。這樣才能把它當成一個對象來看待.加了引號會當成字符串來看待。


通過反射,來執行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的枚舉不好用,還不如直接將 這些字典 存到庫中,建造一個字典類來處理,剛方便.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章