2015-11-03 68 views
0

我试图用百里香叶形式更新某个实体的某些属性。春季数据MVC +百里香叶:更新实体

我做了一个控制器,将DTO添加到模型中。这样我就不必为视图发送不必要的员工属性。

这个设置让我试图修改员工的属性(点击窗体上的编辑按钮)时出现错误:

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

显然我的设置不会因为日期和List对象的工作我有在我的DTO。

我该如何解决这个问题?我是否需要编写一些转换器?我怎么做?

是否有更简单的方法来编辑实体的属性?我的意思是比@SessionAttributes("employee"),DTO's,Mapper,Converter,...更简单的方法...这看起来很简单,但我无法实现它,我有这种感觉,我加入了很多东西(DTO,mappers,converter? ,...)只是为了能够编辑实体的属性。

实体:

@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 
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; 
    } 
} 

电脑板:

@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