Java SpringMVC的问题:注释驱动

Java SpringMVC的问题:注释驱动,java,spring,Java,Spring,我有一个像这样的控制器 @RequestMapping(value = {TABLE_URL}, method = RequestMethod.POST) @ResponseBody public TableModel checkAvailability(@ModelAttribute TableQueryForm TableQueryForm, TableContext table, BindingResult bindingResult) throws Exception

我有一个像这样的控制器

@RequestMapping(value = {TABLE_URL}, method = RequestMethod.POST)
@ResponseBody
public TableModel checkAvailability(@ModelAttribute TableQueryForm TableQueryForm, 
        TableContext table, BindingResult bindingResult) throws Exception {
    // body
}
这里TableContext是一个接口,它有一个实现,并且工作良好

最近,我需要添加一个自定义日期格式化程序,所以在添加它以启用它之后,我添加了一行

<mvc:annotation-driven conversion-service="conversionService"/>

该类的实现没有定义构造函数,因此默认情况下应该激活默认构造函数。我不知道为什么会这样。请帮我解决这个问题。

需要一个空构造函数通过持久性框架的反射创建一个新实例。如果没有为类提供任何带参数的附加构造函数,则不需要提供空构造函数,因为每个默认值都有一个构造函数@u6f6o


您可能提供了额外的构造函数,因此您也应该尝试实现一个空构造函数。

您使用的是Java注释配置还是XML配置,如果您使用的是Java注释配置,那么您需要做的就是删除XML配置文件,使其重新工作


如果这不能解决您的问题,请提供您的配置和控制器类以帮助解决问题。

如果不提供适当的配置,在spring处理程序中注入自定义java接口是不可能的。请注意“自定义”一词,因为Spring可以注入其他接口的实现,如HttpServletRequest、HttpServletResponse、Reader、Writer等。在这些情况下,Spring注入了适当的具体实现。对于自定义java类(如果它是唯一的接口),这不可能的原因可以从您得到的错误堆栈跟踪中看出。如果您的接口没有自定义处理程序解析器,则解析逻辑将回退到默认的ModelAttributeMethodProcessor上,该处理器在所有情况下都会尝试为所述接口类查找构造函数,但由于在java中接口不能有构造函数,因此它会失败(请注意此处带有fails的行)

如果我的测试控制器是

 @RestController
    @RequestMapping("/test")
    public class TestController {   

        @GetMapping("test")
        public String withParam(TestInterface testInterface) {
            return "test";
        }
我和你犯了同样的错误

Caused by: java.lang.IllegalStateException: No primary or default constructor found for interface com.shailendra.TestInterface
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:212)
    at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:84)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:132)
但是如果我在下面使用

@RestController
@RequestMapping("/test")
public class TestController {   

    @GetMapping("test")
    public String withParam(TestInterfaceImpl test) {
        return "test";
    }
我得到了正确的回答


如果接口注入工作正常,那么看起来您之前配置了一个合适的HandlerMethodArgumentResolver,但不知何故,由于您的更改,现在它没有被选中(可能是因为配置被排除在spring扫描之外)

我构建了一个类似您的项目,它工作得很好,但是我不知道你的bean中有什么属性。 您可以根据实际代码进行调整

public interface TableContext {

    Long getDate();
}

public class TableContextImpl implements TableContext{

    private Long date;

    private String tableName;
    //getter setter ...
}
控制器

public String testOne(@RequestParam("tableContext") TableContext tableContext)
配置

    <context:annotation-config/>

    <context:component-scan base-package="com.test.controller"/>

    <mvc:annotation-driven conversion-service="conversionService"/>

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="tableContextFormatter"/>
           </set>
        </property>
    </bean>

    //this one is your custom formatter
    <bean id="tableContextFormatter" class="com.test.controller.TableContextFormatter"></bean>

//这是您的自定义格式化程序
格式化程序

public class TableContextFormatter implements Converter<String, TableContext> {


    @Override
    public TableContext convert(String s) {
        TableContext tc = null;
        if ( null != s ){
            tc = new TableContextImpl();
            //your formatting rules here
            ((TableContextImpl) tc).setDate(Long.parseLong(s));
        }
    return tc;
    }
公共类TableContextFormatter实现转换器{
@凌驾
公共TableContext转换(字符串s){
TableContext tc=null;
如果(null!=s){
tc=新的TableContextImpl();
//你的格式规则在这里
((TableContextImpl)tc).setDate(Long.parseLong(s));
}
返回tc;
}

}

我使用的是接口,而实现类没有其他构造函数。实现类是否扩展了另一个类?您不必为类提供任何构造函数,但在执行此操作时必须小心。编译器会自动为任何没有构造函数的类提供一个无参数的默认构造函数。此默认构造函数将调用超类的无参数构造函数。在这种情况下,如果超类没有无参数构造函数,编译器会抱怨,因此必须验证它是否有。如果您的类没有显式的超类,那么它有一个隐式的Object超类,它确实有一个无参数构造函数-Java Documentation是一个现有的代码,工作正常,没有我提到的新标记。你能提供更多关于TableContext的信息吗?你是对的,我覆盖了现有的WebMvcConfigurationSupport谢谢
public String testOne(@RequestParam("tableContext") TableContext tableContext)
    <context:annotation-config/>

    <context:component-scan base-package="com.test.controller"/>

    <mvc:annotation-driven conversion-service="conversionService"/>

    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <ref bean="tableContextFormatter"/>
           </set>
        </property>
    </bean>

    //this one is your custom formatter
    <bean id="tableContextFormatter" class="com.test.controller.TableContextFormatter"></bean>
public class TableContextFormatter implements Converter<String, TableContext> {


    @Override
    public TableContext convert(String s) {
        TableContext tc = null;
        if ( null != s ){
            tc = new TableContextImpl();
            //your formatting rules here
            ((TableContextImpl) tc).setDate(Long.parseLong(s));
        }
    return tc;
    }