2015-11-03 5 views
0

Я пытаюсь обновить некоторые атрибуты объекта с тимелеафа.Spring Data MVC + Thymeleaf: объект обновления

Я сделал контроллер, который добавляет DTO к модели. Таким образом, мне не нужно отправлять ненужные атрибуты сотрудника в представление.

Эта настройка дает мне ошибку при попытке изменить атрибут Employee (нажав на кнопку редактирования на форме):

There was an unexpected error (type=Bad Request, status=400). 
Validation failed for object='employeeDTO'. Error count: 2 

Видимо моя установка не работает из-за даты и объектов списка У меня в моем DTO.

Как это решить? Нужно ли писать некоторые конвертеры? Как мне это сделать?

Нет ли более простого способа редактировать атрибуты сущности? Я имею в виду более простой способ, чем @SessionAttributes("employee"), DTO, Mapper, Converter, ... Это кажется такой простой функциональностью, но я не могу заставить ее работать, и у меня есть ощущение, что я добавляю много вещей (DTO, mappers, конвертер? , ...), чтобы иметь возможность редактировать атрибут объекта.

Сущности:

@Entity 
public class Employee { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    private String firstName; 
    private String lastName; 
    private Date birthDate; 
    @OneToMany(fetch = FetchType.EAGER) 
    private List<Car> carHistory = new ArrayList<Car>(); 

    // constructors 

    // getters and setters 
} 

@Entity 
public class Car { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 
    @Enumerated(EnumType.STRING) 
    private CarStatus status; 
    private String plate; 

    // constructors 
    // getters & setters 

    public enum CarStatus { 
     FREE, ORDERED, IN_USE, INACTIVE 
    } 

} 

Repository:

@Repository 
public interface EmployeeRepository extends JpaRepository<Employee, Long> { 
} 

Услуги:

@Service 
public class EmployeeService { 
    private EmployeeRepository employeeRepository; 

    @Autowired 
    public EmployeeService(EmployeeRepository employeeRepository) { 
     this.employeeRepository = employeeRepository; 
    } 

    public void updateEmployee(Employee employee){ 
     employeeRepository.saveAndFlush(employee); 
    } 
} 

Сотрудник DTO:

public class EmployeeDTO implements Serializable{ 

    private String firstName; 
    private String lastName; 
    private Date birthDate; 
    private List<Car> carHistory; 

    // getters & setters 
} 

DTO картостроитель:

public class EmployeeMapper { 

    public static Employee mapEmployeeDTOToEmployeeObject(EmployeeDTO dto, Employee employee){ 
     employee.setFirstName(dto.getFirstName()); 
     employee.setLastName(dto.getLastName()); 
     employee.setBirthDate(dto.getBirthDate()); 
     employee.setCarHistory(dto.getCarHistory()); 
     return employee; 
    } 

    public static EmployeeDTO mapEmployeeToEmployeeObject(Employee employee){ 
     EmployeeDTO dto = new EmployeeDTO(); 
     dto.setFirstName(employee.getFirstName()); 
     dto.setLastName(employee.getLastName()); 
     dto.setBirthDate(employee.getBirthDate()); 
     dto.setCarHistory(employee.getCarHistory()); 
     return dto; 
    } 
} 

Conroller:

@Controller 
@RequestMapping("/manage") 
@SessionAttributes("employee") 
public class ManageEmployeesController { 

    @Autowired 
    EmployeeService employeeService; 

    @RequestMapping("/employees") 
    public String manageEmployee(Model model){ 
     model.addAttribute("employees", employeeService.getAllEmployees()); 
     return "manage-employee"; 
    } 

    @RequestMapping(value = "/employee/{employeeId}", method = RequestMethod.GET) 
    public String employeeDetails(@PathVariable("employeeId") Long id, Model model){ 
     Employee emp = employeeService.getEmployeeById(id); 
     model.addAttribute("employee", EmployeeMapper.mapEmployeeToEmployeeObject(emp)); 
     return "manage-employee-details"; 
    } 

    @RequestMapping(value = "/employee/{employeeId}", method = RequestMethod.POST) 
    public String updateEmployeeDetails(@PathVariable("employeeId") Long id, EmployeeDTO employeeWithNewValues){ 
     Employee currentEmployee = employeeService.getEmployeeById(id); 
     employeeService.updateEmployee(EmployeeMapper.mapEmployeeDTOToEmployeeObject(employeeWithNewValues, currentEmployee)); 
     return "redirect:/fleetmanager/employees"; 
    } 
} 

Thymeleaf форма:

<form role="form" method="post" th:object="${employee}"> 
    <h2>Personal details</h2> 
    <table> 
     <tr> 
      <td>First name:</td> 
      <td> 
       <input type="text" th:readonly="true" th:value="*{firstName}" th:field="*{firstName}"/> 
      </td> 
     </tr> 
     <tr> 
      <td>Last name:</td> 
      <td> 
       <input type="text" th:value="*{lastName}" th:field="*{lastName}"/> 
      </td> 
     </tr> 
     <tr> 
      <td>Birthdate:</td> 
      <td> 
       <input type="text" th:value="*{birthDate}" th:field="*{birthDate}"/> 
      </td> 
     </tr> 
     <tr th:each="car : *{carHistory}"> 
      <td th:text="${car.plate}">Plate</td> 
     </tr> 
    </table> 
    <input type="submit" value="Edit"/> 
</form> 

ответ

0

При использовании дат в объектах модели, связанных с полями формы, вам необходимо указать формат, в котором даты представлены в HTTP-запросе. Для этого вам нужно определить PropertyEditor.

class DateEditor extends PropertyEditorSupport { 
    private static final String FORMAT = "MMMMM dd, yyyy"; // Or any valid date format. 

    public String getAsText() { 
    return getValue() != null 
      ? new SimpleDateFormat(FORMAT).format(getValue()) 
      : null; 
    } 

    public void setAsText(final String value) { 
    try { 
     setValue(new SimpleDateFormat(FORMAT).parse(value)); 
    } 
    catch (final ParseException e) { 
     // Log error. 
    } 
    } 
} 

Затем настройте контроллер, чтобы использовать этот редактор.

public class ManageEmployeesController { 
    @InitBinder 
    public void initBinder(final WebDataBinder binder) { 
    binder.registerCustomEditor(Date.class, new DateEditor()); 
    } 
} 

Теперь, когда Spring MVC встречает поле формы переплета типа Date, он будет использовать этот PropertyEditor для преобразования и из String.

Смежные вопросы