0

我有一个与学科类有一对多关联的学生类:

public class Student implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = -779930820340758193L;
    private int studentId;
    private String studentName;
    private List<Subject> subjectList;


    public Student(int studentId, String studentName, List<Subject> subjectList) {
        super();
        this.studentId = studentId;
        this.studentName = studentName;
        this.subjectList = subjectList;
    }
    public Student() {
    }
    public int getStudentId() {
        return studentId;
    }
    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    public List<Subject> getSubjectList() {
        return subjectList;
    }
    public void setSubjectList(List<Subject> subjectList) {
        this.subjectList = subjectList;
    }
    @Override
    public String toString() {
        return "Student [studentId=" + studentId + ", studentName="
                + studentName + ", subjectList=" + subjectList + "]";
    }


}

主题:

public class Subject implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 7135393884889475409L;
    private int subjectId;
    private String subjectName;

    public Subject(int subjectId, String subjectName) {
        super();
        this.subjectId = subjectId;
        this.subjectName = subjectName;
    }
    public int getSubjectId() {
        return subjectId;
    }
    public void setSubjectId(int subjectId) {
        this.subjectId = subjectId;
    }
    public String getSubjectName() {
        return subjectName;
    }
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + subjectId;
        result = prime * result
                + ((subjectName == null) ? 0 : subjectName.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Subject other = (Subject) obj;
        if (subjectId != other.subjectId)
            return false;
        if (subjectName == null) {
            if (other.subjectName != null)
                return false;
        } else if (!subjectName.equals(other.subjectName))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Subject [subjectId=" + subjectId + ", subjectName="
                + subjectName + "]";
    }

}

我的控制器返回所有科目的列表以及学生注册的科目,以便在视图中默认检查它们。

控制器:

public class HelloController{

   @RequestMapping(value = "", method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");

      List<Subject> allList = new ArrayList<Subject>();
      allList.add(new Subject(1,"English"));
      allList.add(new Subject(2,"Maths"));
      allList.add(new Subject(3,"Science"));
      allList.add(new Subject(4,"Social"));
      allList.add(new Subject(5,"Tamil")); 

      List<Subject> enrolledList = new ArrayList<Subject>();
      enrolledList.add(new Subject(1,"English")); 
      enrolledList.add(new Subject(3,"Science"));

      Student student = new Student(1,"SRI",enrolledList);
      model.addAttribute("student", student);
      model.addAttribute("availableList", allList);
      return "home";
   }

   @RequestMapping(value = "save" , method = RequestMethod.POST)
   public String saveStudent(@ModelAttribute Student student , ModelMap model){
       System.out.println(">>>>>>>>>>>>"+student);
       model.addAttribute("finalStudent", student); 
       return "success";
   }

主页.jsp

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
<title>Hello World</title>
</head>
<body>
    <h2>${student.studentName}</h2>
    <form:form method="POST" action="save" modelAttribute="student">
        <form:checkboxes title="Subjects taken" path="subjectList"
            items="${availableList}" itemLabel="subjectName" element="div" />
        <input type = "submit" value = "Save"/>
    </form:form>
</body>
</html>

但是,在这种形式的总结中,我收到以下错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'student' on field 'subjectList': rejected value [Subject [subjectId=1, subjectName=English],Subject [subjectId=3, subjectName=Science]]; codes [typeMismatch.student.subjectList,typeMismatch.subjectList,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.subjectList,subjectList]; arguments []; default message [subjectList]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'subjectList'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.sri.test.Subject] for property 'subjectList[0]': no matching editors or conversion strategy found]
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

有人能帮我吗??提前致谢...

4

2 回答 2

0

您需要实现StringToSubjectConverter将提交的字符串转换为Subject对象的类:

public class StringToSubjectConverter implements Converter<String, Subject> {
  @Override
  public Subject convert(String s) {
    return ...; // your code to convert from `String` to `Subject`
  }
}

并使用 Spring Conversion Service 注册此转换器:

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

  <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
      <set>
        <bean class="package.StringToSubjectConverter" />
      </set>
    </property>
  </bean>
于 2013-08-03T11:30:12.307 回答
0

我已经解决了你的问题。在这里,您尝试将 Subject 对象的 String 数组绑定到 Subject Object 的 List ,这是不可能将“String [] subject”转换为 List 的,这是您通过使用 checkboxe 获得的以下值

"Subject [subjectId=1,subjectName=English]"

由于 toString 方法被覆盖,这种输出格式是在选择您的主题后出现的。

现在,spring 在内部尝试将此 String 或 String[]{ in case of multiple selection} 转换为您的列表。即使使用 convert() 方法,也无法转换。

因此,您必须在 save 方法中创建逻辑,首先从 String[] 中提取这些值,然后在从提取的值创建 Subject 后将其设置到 Subject 列表中。

然后你需要将它设置到 List 方法的 setter 中。

这是下面的代码,修改了两种方法

1) 你的 Subject 类的 toString

@Override
public String toString() {
    return "subjectId=" + subjectId + ",subjectName="+ subjectName;
} 

2) HelloController 的保存方法

@RequestMapping(value = "save.do", method = RequestMethod.POST)
public String saveStudent(@ModelAttribute Student student,
        BindingResult result, HttpServletRequest request, ModelMap model) {
    System.out.println(">>>>>>>>>>>>" + student);
    int i = 0;

    List<Subject> lSubjects=new ArrayList<Subject>();
    String[] subjectsInString = request.getParameterValues("subjectList");
    String[] eachSubject=null;
    Subject subject=null;
    int subjectId=0;
    String subjectName=null;

    if (result.hasErrors()) {

        List<FieldError> fieldErrors = result.getFieldErrors();
        while (i < fieldErrors.size()) {
            System.out.println("Error: " + fieldErrors.get(i));
            i++;
        }

        for (String subjectInString : subjectsInString) {
            System.out.println(subjectInString);
            eachSubject=subjectInString.split(",");
            for(String value:eachSubject){
                if(value.contains("subjectId"))
                subjectId=Integer.parseInt(value.substring(value.lastIndexOf('=')+1,value.length()));

                if(value.contains("subjectName"))
                subjectName=value.substring(value.lastIndexOf('=')+1,value.length());

                /**/
            }

            subject=new Subject(subjectId, subjectName);
            lSubjects.add(subject);
            //eachSubject
        }
        student.setSubjectList(lSubjects);
        System.out.println("Subject List[ "+student.getSubjectList()+" ]");

    } else {
        model.addAttribute("finalStudent", student);
    }
    return "success";

}

我希望这会对您有所帮助,如果您仍然遇到问题,请告诉我。

于 2013-08-04T10:47:40.997 回答