第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

使用Java泛型為實(shí)體實(shí)現(xiàn)轉(zhuǎn)換器

使用Java泛型為實(shí)體實(shí)現(xiàn)轉(zhuǎn)換器

慕尼黑5688855 2019-12-04 11:10:53
我正在使用Spring和Hibernate進(jìn)行JSF項(xiàng)目,其中除其他外,還有許多Converter遵循相同模式的s:getAsObject 接收對(duì)象id的字符串表示形式,將其轉(zhuǎn)換為數(shù)字,并獲取給定種類和給定id的實(shí)體getAsString 接收和實(shí)體,并返回轉(zhuǎn)換為的對(duì)象的ID String該代碼實(shí)質(zhì)上是以下代碼(省略了檢查):@ManagedBean(name="myConverter")@SessionScopedpublic class MyConverter implements Converter {    private MyService myService;    /* ... */    @Override    public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {        int id = Integer.parseInt(value);        return myService.getById(id);    }    @Override    public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {        return ((MyEntity)value).getId().toString();    }}鑒于有大量Converter完全像這樣的s(當(dāng)然MyService和類型除外MyEntity),我想知道是否值得使用單個(gè)通用轉(zhuǎn)換器。泛型本身的實(shí)現(xiàn)并不困難,但是我不確定聲明Bean的正確方法??赡艿慕鉀Q方案如下:1-編寫通用實(shí)現(xiàn),我們稱之為MyGenericConverter,沒有任何Bean批注2-將特定的轉(zhuǎn)換器廣告編寫為的子類,MyGenericConverter<T>并根據(jù)需要對(duì)其進(jìn)行注釋:@ManagedBean(name="myFooConverter")@SessionScopedpublic class MyFooConverter implements MyGenericConverter<Foo> {    /* ... */}在編寫本文時(shí),我意識(shí)到也許并不是真的需要泛型,所以也許我可以簡單地編寫具有這兩種方法的實(shí)現(xiàn)的基類,并根據(jù)需要編寫子類。有一些非瑣碎的細(xì)節(jié)需要處理(例如,我必須以MyService某種方式抽象類的事實(shí)),所以我的第一個(gè)問題是:值得為之煩惱嗎?如果是這樣,還有其他方法嗎?
查看完整描述

2 回答

?
阿晨1998

TA貢獻(xiàn)2037條經(jīng)驗(yàn) 獲得超6個(gè)贊

最簡單的方法是讓您的所有JPA實(shí)體都從這樣的基本實(shí)體擴(kuò)展:


public abstract class BaseEntity<T extends Number> implements Serializable {


    private static final long serialVersionUID = 1L;


    public abstract T getId();


    public abstract void setId(T id);


    @Override

    public int hashCode() {

        return (getId() != null) 

            ? (getClass().getSimpleName().hashCode() + getId().hashCode())

            : super.hashCode();

    }


    @Override

    public boolean equals(Object other) {

        return (other != null && getId() != null

                && other.getClass().isAssignableFrom(getClass()) 

                && getClass().isAssignableFrom(other.getClass())) 

            ? getId().equals(((BaseEntity<?>) other).getId())

            : (other == this);

    }


    @Override

    public String toString() {

        return String.format("%s[id=%d]", getClass().getSimpleName(), getId());

    }


}

請(qǐng)注意,擁有一個(gè)適當(dāng)?shù)膃quals()(和hashCode())很重要,否則您將面臨“ 驗(yàn)證錯(cuò)誤:值無效”。該Class#isAssignableFrom()測(cè)試是避免如Hibernate基于代理失敗的測(cè)試,而不需要回落到休眠特定Hibernate#getClass(Object)的輔助方法。


并擁有這樣的基礎(chǔ)服務(wù)(是的,我忽略了您使用Spring的事實(shí);這只是給出基本思想):


@Stateless

public class BaseService {


    @PersistenceContext

    private EntityManager em;


    public BaseEntity<? extends Number> find(Class<BaseEntity<? extends Number>> type, Number id) {

        return em.find(type, id);

    }


}

并實(shí)現(xiàn)轉(zhuǎn)換器如下:


@ManagedBean

@ApplicationScoped

@SuppressWarnings({ "rawtypes", "unchecked" }) // We don't care about BaseEntity's actual type here.

public class BaseEntityConverter implements Converter {


    @EJB

    private BaseService baseService;


    @Override

    public String getAsString(FacesContext context, UIComponent component, Object value) {

        if (value == null) {

            return "";

        }


        if (modelValue instanceof BaseEntity) {

            Number id = ((BaseEntity) modelValue).getId();

            return (id != null) ? id.toString() : null;

        } else {

            throw new ConverterException(new FacesMessage(String.format("%s is not a valid User", modelValue)), e);

        }

    }


    @Override

    public Object getAsObject(FacesContext context, UIComponent component, String value) {

        if (value == null || value.isEmpty()) {

            return null;

        }


        try {

            Class<?> type = component.getValueExpression("value").getType(context.getELContext());

            return baseService.find((Class<BaseEntity<? extends Number>>) type, Long.valueOf(submittedValue));

        } catch (NumberFormatException e) {

            throw new ConverterException(new FacesMessage(String.format("%s is not a valid ID of BaseEntity", submittedValue)), e);

        }

    }


}

請(qǐng)注意,它被注冊(cè)為@ManagedBean而不是@FacesConverter。這個(gè)技巧可以讓您通過例如在轉(zhuǎn)換器中注入服務(wù)@EJB。另請(qǐng)參見如何在@FacesConverter中注入@ EJB,@ PersistenceContext,@ Inject,@ Autowired等?因此,您需要引用converter="#{baseEntityConverter}"而不是converter="baseEntityConverter"。


如果您碰巧將此類轉(zhuǎn)換器更多地用于UISelectOne/ UISelectMany組件(<h:selectOneMenu>和朋友),您可能會(huì)發(fā)現(xiàn)OmniFaces SelectItemsConverter更加有用。它基于可用的值進(jìn)行轉(zhuǎn)換,<f:selectItems>而不是每次都進(jìn)行(可能很昂貴)DB調(diào)用。


查看完整回答
反對(duì) 回復(fù) 2019-12-04
  • 2 回答
  • 0 關(guān)注
  • 3073 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)