我想在Spring MVC項目中使用Spring的DomainClassConverter功能。 (我只有Spring MVC和Spring的基本知識,對於任何天真的問題都會提前道歉)。在Spring MVC中使用Spring的DomainClassConverter的問題
從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)
我從以上可以理解的是,我沒有寫一個查找方法和Spring提供的User
對象。因此,這些是我所做的步驟:
在applicationcontext.xml
中包含下面的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>
包括這種依賴性在我pom.xml
每Spring Data REST DOC:
<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是這樣的:
@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 本地主機時: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
的真正好處是什麼?
每奧利弗·基爾克建議更新 - 仍然不能正常工作,同樣的錯誤
該文件描述:
<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…
}
Java的配置文件中使用的實例組裝從和resource2。 (可能需要清理)
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();
}
}
添加下面的bean定義在applicationContext.xml
<bean class="com.rl.userservice.controller.WebConfig"/>
什麼是'applicationcontext.xml'它是你的調度程序servlet上下文嗎? http://stackoverflow.com/questions/3652090/difference-between-applicationcontext-xml-and-spring-servlet-xml-in-spring MVC標籤和轉換器可能會在調度程序servlet使用的上下文中聲明 - 而不是根應用程序Web應用程序上下文 –
請勿定義您自己的轉換服務(或自定義UserConverter)。刪除你的'conversionService' bean定義! –
@Pavel你能詳細說明一下嗎?在這種情況下,我認爲轉換服務處於錯誤的上下文環境中,所以它被調度程序servlet中的轉換服務所遮蔽,但通常顯式聲明自定義bean沒有任何問題。 –