动态类型种姓弹簧路径变量

Posted

技术标签:

【中文标题】动态类型种姓弹簧路径变量【英文标题】:Dynamic type caste Spring pathvariable 【发布时间】:2018-11-11 21:09:09 【问题描述】:

我计划使用 JPA 创建一个简单的 Spring Rest 服务项目,它将根据路径变量中给出的实体名称和实体 ID 从数据库中获取详细信息。

考虑以下代码。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
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 com.ds.dao.EntityDAO;
import com.ds.entities.Employees;

import javax.persistence.Entity;
@Controller
@RequestMapping("/")
public class DynaRestController 

@Autowired
EntityDAO entityDAO;


@RequestMapping(value = "entityName/enityId",method = RequestMethod.GET)
public @ResponseBody Object getEntity(@PathVariable("entityName") String entityName,@PathVariable("enityId") Object id) 
    return entityDAO.getEntityById(entityName, id);



实体 DAO 类

public class EntityDAO 
@Autowired
EntityManager entityManager;


public Object getEntityById(String entityName, Object id) 
    EntityType<?> entityType = getEntityByName(entityName);
    Object idcasted = entityType.getIdType().getJavaType().cast(id);
    System.out.println(idcasted.getClass().getName());
    Object entity = entityManager.find(entityType.getJavaType(), idcasted);
    System.out.println("Entity.. Name .." + entityName);
    // Employees entity = session.load(Employees.class, id);
    return entity;



private EntityType<?> getEntityByName(String name) 
    Set<EntityType<?>> entities = entityManager.getMetamodel().getEntities();
    for (Iterator<EntityType<?>> iterator = entities.iterator(); iterator.hasNext();) 
        EntityType<?> entityType = (EntityType<?>) iterator.next();
        if (entityType.getName().equals(name))
            return entityType;
    

    return null;

员工类

@Configurable
@Entity
@Table(name = "employees", catalog = "employees")
public class Employees implements java.io.Serializable 

/**
 * 
 */
private static final long serialVersionUID = 1L;
private int empNo;
private Date birthDate;
private String firstName;
private String lastName;
private String gender;
private Date hireDate;
private Set<Titles> titleses = new HashSet<Titles>(0);
private Set<Salaries> salarieses = new HashSet<Salaries>(0);
private Set<DeptEmp> deptEmps = new HashSet<DeptEmp>(0);
private Set<DeptManager> deptManagers = new HashSet<DeptManager>(0);

public Employees() 


public Employees(int empNo, Date birthDate, String firstName, String lastName, String gender, Date hireDate) 
    this.empNo = empNo;
    this.birthDate = birthDate;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.hireDate = hireDate;


public Employees(int empNo, Date birthDate, String firstName, String lastName, String gender, Date hireDate,
        Set<Titles> titleses, Set<Salaries> salarieses, Set<DeptEmp> deptEmps, Set<DeptManager> deptManagers) 
    this.empNo = empNo;
    this.birthDate = birthDate;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.hireDate = hireDate;
    this.titleses = titleses;
    this.salarieses = salarieses;
    this.deptEmps = deptEmps;
    this.deptManagers = deptManagers;


@Id
@Column(name = "emp_no", unique = true, nullable = false)
public int getEmpNo() 
    return this.empNo;


public void setEmpNo(int empNo) 
    this.empNo = empNo;


@Temporal(TemporalType.DATE)
@Column(name = "birth_date", nullable = false, length = 10)
public Date getBirthDate() 
    return this.birthDate;


public void setBirthDate(Date birthDate) 
    this.birthDate = birthDate;


@Column(name = "first_name", nullable = false, length = 14)
public String getFirstName() 
    return this.firstName;


public void setFirstName(String firstName) 
    this.firstName = firstName;


@Column(name = "last_name", nullable = false, length = 16)
public String getLastName() 
    return this.lastName;


public void setLastName(String lastName) 
    this.lastName = lastName;


@Column(name = "gender", nullable = false, length = 2)
public String getGender() 
    return this.gender;


public void setGender(String gender) 
    this.gender = gender;


@Temporal(TemporalType.DATE)
@Column(name = "hire_date", nullable = false, length = 10)
public Date getHireDate() 
    return this.hireDate;


public void setHireDate(Date hireDate) 
    this.hireDate = hireDate;


@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<Titles> getTitleses() 
    return this.titleses;


public void setTitleses(Set<Titles> titleses) 
    this.titleses = titleses;


@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<Salaries> getSalarieses() 
    return this.salarieses;


public void setSalarieses(Set<Salaries> salarieses) 
    this.salarieses = salarieses;


@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
@JsonBackReference
public Set<DeptEmp> getDeptEmps() 
    return this.deptEmps;


public void setDeptEmps(Set<DeptEmp> deptEmps) 
    this.deptEmps = deptEmps;


@OneToMany(fetch = FetchType.LAZY, mappedBy = "employees")
public Set<DeptManager> getDeptManagers() 
    return this.deptManagers;


public void setDeptManagers(Set<DeptManager> deptManagers) 
    this.deptManagers = deptManagers;

当我使用以下代码动态转换路径变量时

Object idcasted = entityType.getIdType().getJavaType().cast(id);
Object entity = entityManager.find(entityType.getJavaType(), idcasted);

它正在抛出 ClassCastExpcetion

java.lang.ClassCastException:无法将 java.lang.String 转换为 int 在 java.lang.Class.cast(Class.java:3369) ~[na:1.8.0_112] 在 com.techm.att.ds.dao.EntityDAO.getEntityById(EntityDAO.java:33) ~[classes/:na] 在 com.techm.att.ds.dao.EntityDAO$$FastClassBySpringCGLIB$$8e64d745.invoke() ~[classes/:na] 在 org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.13.RELEASE.jar:4.3.13.RELEASE] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.13.RELEASE.jar:4.3.13.RELEASE]

任何帮助都将受到高度评价..

【问题讨论】:

Id 是一个字符串,不能通过 cast 方法转换为整数。实体的 id 类型是整数。 docs.oracle.com/javase/7/docs/api/java/lang/… 是的,我知道字符串不能被类型转换为 Int,我正在将路径变量类型转换为对象类型。那为什么它会抛出 String 的异常..? ,@PathVariable("enityId") 对象id) 我给你写个小例子 【参考方案1】:

我给你写一个关于 cmets 的简单例子。 这是相同的行为。你的 RestController 实际上得到一个字符串:

  public static void main(String[] args) 
    Object myString = "myString";
    System.out.println(myString.getClass()); // class java.lang.String
    int.class.cast(myString);

cast 方法检查给定值的实例,但失败:

 public T cast(Object obj) 
    if (obj != null && !isInstance(obj))
        throw new ClassCastException(cannotCastMsg(obj));
    return (T) obj;

【讨论】:

谢谢@PL4gu33,我明白了这个问题。希望你能理解我的问题。你能给我这个问题的解决方案吗?我想要一个通用的解决方案,其中应根据 id 类型动态获取密钥。 是的,我理解你的问题,但如果你想尝试将任何类型转换为任何其他类型,你总会遇到一些转换问题。您必须在某个地方处理这些错误。对于 String 到 int,您可以轻松编写“Integer.parseInt(myString)”,但您希望它是动态的“.cast(..)”。我还不知道这应该如何工作,因为当类型不同时,你总是会遇到这样的问题。

以上是关于动态类型种姓弹簧路径变量的主要内容,如果未能解决你的问题,请参考以下文章

静态与动态类型

动态类型是否与动态(后期)绑定相同?

Pythonpython动态类型

Python动态强类型解释型语言

不需要声明变量类型的语言的质量是弱类型还是动态类型的例子

Python的动态类型