我试图在我的Spring MVC项目中使用Spring的DomainClassConverter功能。 (我对Spring MVC和Spring只有非常基本的知识,请提前为任何天真的问题道歉。)
来自API docs:
The DomainClassConverter allows you to use domain types in your Spring MVC controller
method signatures directly, so that you don't have to manually lookup the instances via
the repository: (PS: Example 1.20)
我从上面的理解是,我不必编写finder方法,Spring提供User
对象。所以这些是我做的步骤:
在applicationcontext.xml
。
<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.rl.userservice.controller.UserConverter"/>
</list>
</property>
根据Spring Data REST doc:
在我的pom.xml
中包含此依赖项
<dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-rest-webmvc</artifactId> <version>2.0.0.BUILD-SNAPSHOT</version> </dependency> </dependencies>
我的控制器如下所示:
@Controller @RequestMapping(value = "/api/newuser") public class NewUserServiceController { @Autowired NewUserRepository newUserRepository; @RequestMapping("/{id}") public String showUserForm(@PathVariable("id") NewUser newUser, Model model) { model.addAttribute("newUser", newUser); return "userForm"; } }
存储库是这样的:
@Repository public interface NewUserRepository extends JpaRepository<NewUser, Integer> { }
这是我的转换服务:
final class UserConverter implements Converter<Integer, NewUser> {
NewUserRepository newUserRepository;
public NewUser convert(Integer username) {
return newUserRepository.findOne(username);
}
}
当我运行程序时,tomcat启动成功,但是当访问URL localhost:8080 / userservice / api / newuser / 1 时,我得到以下异常:
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type
'com.mpp.userservice.domain.NewUser'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
[java.lang.String] to required type
[com.mpp.userservice.domain.NewUser]: no matching editors or
conversion strategy found
org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:71)
org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45)
org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:595)
org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:101)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type
[com.mpp.userservice.domain.NewUser]: no matching editors or
conversion strategy found
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:264)
org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:93)
org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:61)
org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45)
org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:595)
org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:101)
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77)
org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:123)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.29 logs.
mpp.
虽然不是最好的代码,但这是我的控制器:
public @ResponseBody ResponseEntity<ModelMap> getUserTypeJSON(@PathVariable("userID" String userID, HttpServletResponse response) {
UserType UserType = UserTypeRepository.findOne(id);
model.addAttribute("Name",UserType.getName());
...
}
我引用了一个示例here,但这是使用自定义转换器,但似乎没有使用域转换器服务。请指教。如果我想减少编写CRUD操作的样板代码,这是可行的吗?当我以其他方式获取数据时,DomainClassConverter
的真正好处是什么?
根据Oliver Gierke建议更新 - 仍然无效,同样的错误
该文件描述:
<mvc:annotation-driven conversion-service="conversionService" /> <bean class="org.springframework.data.repository.support.DomainClassConverter"> <constructor-arg ref="conversionService" /> </bean>
所以我更新了applicationcontext.xml
,如下所示,但同样的问题:
<mvc:annotation-driven conversion-service="conversionService"/> <bean class="org.springframework.data.repository.support.DomainClassConverter"> <constructor-arg ref="conversionService" /> </bean> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.rl.userservice.controller.UserConverter"/> </list> </property> </bean>
仍然是同一个问题。
更新:DomainClassConverter适用于Java Config,但不适用于XML方式(至少在这里建议了很多组合以及互联网上的其他地方)。仅针对可能感兴趣的其他人,并在此处获取一些有用的信息。
pom.xml(可能需要清理)
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>2.0.0.M1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.4.3.RELEASE</version>
</dependency>
控制器文件(可能需要清理)
@RequestMapping("/domain/{id}")
public @ResponseBody ResponseEntity<ModelMap> showDomainUserForm(@PathVariable("id") User userMatch, HttpServletResponse response) {
// some code omitted…
ModelMap model = new ModelMap();
model.addAttribute("DOMAIN-MAP","Domain Controller Service");
model.addAttribute("Name",userMatch.getName());
model.addAttribute("Phone",userMatch.getPhone());
// some code omitted…
}
使用resource1和resource2中的示例汇总Java Config文件。 (可能需要清理)
package com.rl.userservice.controller;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.repository.support.DomainClassConverter;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Configuration
@ComponentScan
@EnableWebMvc
public class WebConfig extends WebMvcConfigurationSupport{
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
handlerMapping.setUseSuffixPatternMatch(false);
handlerMapping.setUseTrailingSlashMatch(false);
return handlerMapping;
}
@Bean
public DomainClassConverter<?> domainClassConverter() {
return new DomainClassConverter<FormattingConversionService>(mvcConversionService());
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
在applicationContext.xml
中添加以下bean定义<bean class="com.rl.userservice.controller.WebConfig"/>
答案 0 :(得分:1)
网址为String
,因此{id}
也是String
。因此,您的服务必须能够将String
转换为NewUser
,而不能转换为Integer
。
答案 1 :(得分:0)
请查看relevant section of the reference documentation,了解配置DomainClassConverter
的正确方法。
答案 2 :(得分:0)
答案 3 :(得分:0)
此配置设置自定义转换服务并将其传递给检测和设置控制器的注释扫描机制:
<bean name="conversionService" class="rest.gateway.services.MyConversionService"/>
<mvc:annotation-driven conversion-service="conversionService" />
这是自定义控制器的代码,客户是像User这样的域类:
public class MyConversionService extends DefaultConversionService {
public MyConversionService() {
super();
addConverter(String.class, Customer.class, new Converter<String, Customer>() {
@Override
public Customer convert(String source) {
return new Customer("123456","Doe","John");
}
});
}
}
尝试使用此功能,因为这适用于版本2.0.0.M1:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
<version>2.0.0.M1</version>
</dependency>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>