Собственно вопрос очень старый но решения так и нет.
Обсуждался тут https://stackoverflow.com/questions/43041724/using-converter-with-spring-mvc
и тут https://stackoverflow.com/questions/50173341/field-error-in-object-user-on-field-userprofiles-rejected-value-3
Моя проблема в точности та же самая
За основу взят этот пример http://websystique.com/springmvc/spring-mvc-4-and-spring-security-4-integration-example/
Только пример я расширил с возможностью добавления в базу ролей и привилегий
Для этого модифицировал модель ролей так
@Table(name="USER_PROFILE")
public class UserProfile implements Serializable{
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@NotEmpty
@Column(name="TYPE", unique=true, nullable=false)
private String type;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@NotEmpty
// @ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@ManyToMany(fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@JoinTable(name = "USER_PROFILE_USER_PERMISSION",
joinColumns = { @JoinColumn(name = "USER_PROFILE_ID") },
inverseJoinColumns = { @JoinColumn(name = "USER_PERMISSION_ID") })
private Set<UserPermission> userPermissions = new HashSet<UserPermission>();
public Set<UserPermission> getUserPermissions() {
return userPermissions;
}
public void setUserPermissions(Set<UserPermission> userPermissions) {
this.userPermissions = userPermissions;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof UserProfile))
return false;
UserProfile other = (UserProfile) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public String toString() {
return "UserProfile [id=" + id + ", type=" + type + ", userPermissions=" + userPermissions + "]";
}
}
Метод добавления роли в контроллере
@RequestMapping(value = { "/newprofile" }, method = RequestMethod.POST)
public String saveUserProfile(@Valid UserProfile userProfile, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "profiles";
}
if(!userProfileService.isUserProfileTypeUnique(userProfile.getId(), userProfile.getType())){
FieldError ssoError = new FieldError("userProfile","type",messageSource.getMessage("non.unique.type", new String[]{userProfile.getType()}, Locale.getDefault()));
result.addError(ssoError);
return "newprofile";
}
userProfileService.saveProfile(userProfile);
model.addAttribute("success", "UserProfile " + userProfile.getType() + " registered successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "layouts/registrationsuccess";
}
Конвертор привилегий выглядит так
@Component
public class PrivilegeToUserPermissionConverter implements Converter<Object, UserPermission>{
static final Logger logger = LoggerFactory.getLogger(PrivilegeToUserPermissionConverter.class);
@Autowired
UserPermissionService userPermissionService;
/**
* Gets UserProfile by Id
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
*/
public UserPermission convert(Object element) {
Integer id = Integer.parseInt((String)element);
UserPermission permission= userPermissionService.findById(id);
logger.info("Permission : {}",permission);
return permission;
}
}
Добавить новую роль (UserProfile) невозможно. Возникает ошибка типа
Failed to bind request element: org.springframework.beans.TypeMismatchException: Failed to convert value of type [com.websystique.springmvc.model.UserProfile] to required type [com.websystique.springmvc.model.UserProfile]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [com.websystique.springmvc.model.UserProfile] to type [@javax.validation.Valid com.websystique.springmvc.model.UserProfile] for value 'UserProfile [id=null, type=dgfhsdhsf, userPermissions=[com.websystique.springmvc.model.UserPermission@62ce11d]]'; nested exception is java.lang.ClassCastException: com.websystique.springmvc.model.UserProfile cannot be cast to java.lang.String
Собственно проект тут https://bitbucket.org/yguvin/springmvchibernatewithspringsecurity/src/master/
Проблема в том что регистрация двух конверторов в public class AppConfig extends WebMvcConfigurerAdapter{ приводит к вышеописанной ошибке
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.websystique.springmvc")
public class AppConfig extends WebMvcConfigurerAdapter{
@Autowired
RoleToUserProfileConverter roleToUserProfileConverter;
@Autowired
PrivilegeToUserPermissionConverter privilegeToUserPermissionConverter;
/**
* Configure ViewResolvers to deliver preferred views.
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
/**
* Configure ResourceHandlers to serve static resources like CSS/ Javascript etc...
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/resources/css/**").addResourceLocations("/resources/css/").setCachePeriod(31556926);
registry.addResourceHandler("/resources/img/**").addResourceLocations("/resources/img/").setCachePeriod(31556926);
registry.addResourceHandler("/resources/js/**").addResourceLocations("/resources/js/").setCachePeriod(31556926);
}
/**
* Configure Converter to be used.
* In our example, we need a converter to convert string values[Roles] to UserProfiles in newUser.jsp
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(roleToUserProfileConverter);
registry.addConverter(privilegeToUserPermissionConverter);
}
/**
* Configure MessageSource to lookup any validation/error message in internationalized property files
*/
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
/**Optional. It's only required when handling '.' in @PathVariables which otherwise ignore everything after last '.' in @PathVaidables argument.
* It's a known bug in Spring [https://jira.spring.io/browse/SPR-6164], still present in Spring 4.1.7.
* This is a workaround for this issue.
*/
@Override
public void configurePathMatch(PathMatchConfigurer matcher) {
matcher.setUseRegisteredSuffixPatternMatch(true);
}
}
Косяк Спринга? Не может быть. Тогда что?
Решения задачки в сети нет.
Может ли кто подсказать как выполнить конвертацию данных непосредственно в контроллере, без применения компонентов конверторов?