Как повторно использовать длину поля в форме, проверке и ddl?

Я работаю над приложением Spring с большим количеством форм ввода. Я хотел бы повторно использовать длину поля в аннотациях пользовательского интерфейса, проверки и JPA. Есть ли элегантный способ решить эту проблему. Мое решение на данный момент состоит в том, чтобы использовать константы для объявления длины:

public class Person
{
   public static final int FIRSTNAME_LENGTH = 25;

   @Column(length=FIRSTNAME_LENGTH)
   private String firstName;

   ...
}

а затем повторно использовать константу в валидаторе и Jsp

...

<form:input path="firstName" 
    maxlength="<%= Integer.toString(Person.FIRSTNAME_LENGTH) %>"/>

...

что довольно многословно.

Есть ли более элегантное решение этой проблемы?


person Dominik    schedule 29.11.2009    source источник
comment
Доминик, твое элегантное решение кажется мне довольно умным. Возможно, мне придется использовать это. Тем не менее, хороший вопрос, это то, что каждый должен делать, но, похоже, для него нет встроенного решения.   -  person James McMahon    schedule 18.12.2009
comment
Я рад, что вы разместили награду здесь, я тоже хочу увидеть ответ на этот вопрос. Я бы хотел, чтобы у них была функция для наград сообщества, я бы добавил немного своей репутации.   -  person James McMahon    schedule 18.12.2009


Ответы (3)


Доступ к информации, хранящейся в аннотациях, вполне возможен. На самом деле это их основная цель: хранить метаинформацию о классе/методе/поле. Вот пример того, как получить доступ к длине, хранящейся в аннотации @Column:

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class Person {

   @Column(length=30)
   private String firstName;

   public static void main(String[] args) throws SecurityException, NoSuchFieldException {
      Object person = new Person();
      //find out length    
      System.out.println(person.getClass().getDeclaredField("firstName").getAnnotation(Column.class).length());
   }
}

Вы должны иметь возможность создать некоторый пользовательский тег или bean-компонент для извлечения этой информации в целом.

Нетрудно создавать свои собственные аннотации. Вы можете рассмотреть возможность создания формы, в которой указано, какие поля должны быть включены в форму, как они должны отображаться, описание и т. д. Затем вы могли бы создать общую форму. С другой стороны, вам может не понравиться смешивать домен и представление.

person EJB    schedule 22.12.2009
comment
Это довольно полная строка, знаменитая лаконичность Java жива и здорова. Отличный совет, спасибо. - person James McMahon; 23.12.2009
comment
Просто продолжение, java.lang.Class.getDeclaredField() выдает два проверенных исключения, NoSuchFieldException и SecurityException. Это делает этот метод немного более неуклюжим, и об этом следует помнить, если вы пытаетесь реализовать это решение. - person James McMahon; 07.01.2010

Я задавал аналогичный вопрос, когда использовал Hibernate,

Получение длины столбца из сопоставлений Hibernate?

Однако я не знаю, как получить эту информацию в JPA, но если вы используете Hibernate в качестве базового уровня, вы можете попробовать напрямую получить доступ к Hibernate и реализовать решение, описанное выше.

Однако решение Hibernate столь же элегантно, как и решение, которое вы изложили в своем ответе, с дополнительным недостатком, заключающимся в том, что оно связывает вашу реализацию JPA с Hibernate.

person James McMahon    schedule 18.12.2009

Решение, предоставляемое EJB, считывает аннотированное значение длины столбца. Джеймс МакМахон указал, что это раскрывает реализацию Hibernate. Это можно довольно просто решить с помощью методов геттера. Предполагая, что есть интерфейс для Person с объявленным методом getFirstNameLength:

import javax.persistence.Column;
import javax.persistence.Entity;

@Entity
public class PersonImplementation extends Person {

   @Column(length=30)
   private String firstName;

   public int getFirstNameLength() {
       return this.getClass().getDeclaredField("firstName").getAnnotation(Column.class).length();
   }
}
person Danny Stevens    schedule 09.01.2014