简体   繁体   English

获取大型表单到Spring控制器

[英]Getting large form to Spring controller

I have a form whose purpose is to allow a user to create a new entry in a database table. 我有一个表单,其目的是允许用户在数据库表中创建一个新条目。 The form is very large, ~50 fields in total. 形式非常大,总共约50个领域。 I'm needing a way get all of these values to my controller, though I don't see an easy way. 我需要一种方法将所有这些值传递给我的控制器,尽管我没有看到一个简单的方法。 Every solution I've seen is to have a @RequestParam('field') , but with around 50 fields that is a little crazy. 我见过的每个解决方案都是有一个@RequestParam('field') ,但有大约50个字段有点疯狂。 Maybe if using a @RequestParam Map<T, T> is possible? 也许如果使用@RequestParam Map<T, T>是可能的吗?

What I tried at first was to create an AJAX POST call to 我最初尝试的是创建一个AJAX POST调用

baseapplication.com/add?field1=value1&field2=value2&...&field50=value50

but then the servlet complained about not finding the add.jsp file. 但后来servlet抱怨没有找到add.jsp文件。 This is sort of reasonable because that file does not exist, but I created a controller mapping @RequestMapping(value="/add") so I shouldn't actually need that file. 这是合理的,因为该文件不存在,但我创建了一个映射@RequestMapping(value="/add")的控制器,所以我实际上不需要该文件。 I have another method which creates an AJAX GET call to /search with some url parameters, and that works fine. 我有另一个方法,它创建一个AJAX GET调用/search一些url参数,并且工作正常。 There is also no search.jsp file. 也没有search.jsp文件。

This problem is hard to explain, I hope I did a halfway decent job. 这个问题很难解释,我希望我做了一个中等体面的工作。 Let's look at some code now, with omissions because dealing with ~50 form fields is very lengthy. 现在让我们看一些代码,遗漏因为处理~50个表单字段非常冗长。

Starting with the JavaScript, which initiates this whole process: 从JavaScript开始,它启动整个过程:

ctx = "baseapplication.com"
$('#addNewRecordBtn').on('click', function(){
    var m_insId = document.getElementById('m_insId');
    //This repeats for every field
    var url = ctx + '/add?insuredId=' + m_insId /** + all other fields **/;
    addCase(url);
});

function addCase(url) {
    $.ajax({
        url: url,
        type: 'POST'
    }).success(function(data){
        alert("Successfully added row");
    }).fail(function(jzXHR, textStatus, errorThrown){
        alert(jzXHR);
        alert(textStatus);
        alert(errorThrown);
    });
}

So the flow of this is as follows: The user clicks on the addNewRecordBtn button, which fires the first function. 因此,流程如下:用户单击addNewRecordBtn按钮,该按钮将触发第一个函数。 This function grabs the value of every field in the form, then builds a URL with parameters for each of these values. 此函数获取表单中每个字段的值,然后使用每个值的参数构建一个URL。 The addCase() function is then called, which creates an AJAX POST (not sure what to call this?) to the URL that was just built. 然后调用addCase()函数,它会创建一个AJAX POST(不知道该怎么称呼它?)到刚刚构建的URL。 This function does not succeed, the error alerts provide zero information, but the server console claims Failed to find resource /WEB-INF/views/add.jsp 此功能不成功,错误警报提供零信息,但服务器控制台声称Failed to find resource /WEB-INF/views/add.jsp

Now we move into the controller. 现在我们进入控制器。

@Controller
public class ApplicationController {

    @Autowired
    SpecialClaimsCaseManager caseManager;

    @RequestMapping(value="/add")
    public void addRow(@RequestParam Map<String, String> requestParams) {
        SpecialClaimsCase newCase = new SpecialClaimsCase();

        newCase.setInsuredId(requestParams.get("insuredId"));
        //Repeat this for all parameters

        caseManager.addNewSpecialClaimsCase(newCase);
}

The caseManager.addNewSpecialClaimsCase(newCase) call just creates a DTO object out of this model object, and then adds that new object to the database via some Hibernate magic. caseManager.addNewSpecialClaimsCase(newCase)调用只是从这个模型对象中创建一个DTO对象,然后通过一些Hibernate魔法将该新对象添加到数据库中。 I don't know much about that side, other than it works. 除了有效之外,我对这方面知之甚少。

So, I'm not sure if I'm going about this the right way. 所以,我不确定我是否正确地采取了这种方式。 I hear there's a way to map a model object to a JSP form using Spring's tag library, but that would require a ton of rewriting as the form is huge. 我听说有一种方法可以使用Spring的标签库将模型对象映射到JSP表单,但这需要大量的重写,因为表单很大。 I'm also using Bootstrap to build the interface, and I'm not sure if Bootstrap and Spring's tag library mix well. 我也使用Bootstrap构建接口,我不确定Bootstrap和Spring的标签库是否混合良好。 I can't imagine why not. 我无法想象为什么不呢。

I'm not sure if I need to be using AJAX here or not. 我不确定我是否需要在这里使用AJAX。 I went with it because I don't want the page to have to reload or anything. 我去了,因为我不希望页面必须重新加载或任何东西。 I'm not usually a web developer, so I am sure I am lacking some fundamental knowledge here. 我通常不是网络开发人员,所以我确信我缺乏一些基础知识。

My main question is: given my sitatuation, what is the best way to get this massive form of information into my controller? 我的主要问题是:鉴于我的情况,将这种大量信息传递给我的控制器的最佳方法是什么?

Thanks in advance for reading this wall of text and code and for any assistance you can offer! 提前感谢您阅读此文本和代码墙以及您可以提供的任何帮助!

Create a domain class that has all of these needed fields and generate getters and setters and also a constructor. 创建一个包含所有这些必需字段的域类,并生成getter和setter以及构造函数。 Once you get all these fields/some of these fields POST as json to your controller. 一旦你得到所有这些字段/其中一些字段POST作为json到你的控制器。 The appropriate controller will then call the required service and then the DAO will handle the persistence part. 然后,适当的控制器将调用所需的服务,然后DAO将处理持久性部分。 In short, send the data you need as a JSON object. 简而言之,将您需要的数据作为JSON对象发送。 The json will be made as java object and the operation on the same will be performed. 将json设为java对象,并对其执行相同的操作。

Here is the controller 这是控制器

@Controller
@RequestMapping(value = "/students/association")
public class StudentDepartmentController {

@Autowired
private StudentService studentService;

@Autowired
private StudentDepartmentService studentDepartmentService;

@RequestMapping(value = "/add-department", method = RequestMethod.POST)
public ResponseEntity<StudentDepartment> createStudentDepartmentAssociation(
        @RequestBody final StudentDepartment studentDepartment) {

    StudentDepartment newStudentDepartment;

    // check if the student exists

    Student student = studentService.getStudentByUuid(studentDepartment
            .getStudentUuid().getUuid());

    if (null == student) {

        throw new IllegalArgumentException("No students found!");

    }

    // check the status of student
    if (student.getStatus() == Liveliness.INACTIVE) {
        throw new IllegalArgumentException(
                "cannot create an association with an inactive student! activate student first");
    }

    // check for valid department

    if (null == studentDepartment.getDepartment().getName()) {
        throw new IllegalArgumentException("No such Department");
    }

    // check if the association already exists

    if (null != findOneAssociationAgainstStudent(student)) {
        throw new IllegalArgumentException(
                "cannot create student department association, as "
                        + student.getUsn()
                        + " already present in another association ( "
                        + studentDepartment.getDepartment().getName()
                        + " )");
    }

    try {

        newStudentDepartment = studentDepartmentService
                .createNewAssociation(studentDepartment);

    } catch (DataIntegrityViolationException ex) {

        throw new AutomationTransactionException(
                "cannot create student department association, as "
                        + student.getUsn()
                        + " already present in another association ( "
                        + studentDepartment.getDepartment().getName()
                        + " )", ex);

    }

    return new ResponseEntity<StudentDepartment>(newStudentDepartment,
            HttpStatus.CREATED);
}

private StudentDepartment findOneAssociationAgainstStudent(Student student) {

    return studentDepartmentService.findOneAssociation(student);
}

private StudentDepartment findOne(Uuid uuid) {

    String studentDepartmentUuid = uuid.getUuid();

    return findOne(studentDepartmentUuid);

}

private StudentDepartment findOne(String uuid) {

    return studentDepartmentService.findOne(uuid);

}

@RequestMapping(value = "/delete-association", method = RequestMethod.DELETE)
public ResponseEntity<String> deleteStudentDepartmentAssociationByUuid(
        @RequestBody final StudentDepartment studentDepartment) {

    // check if association exists
    StudentDepartment association = findOne(studentDepartment.getUuid());
    if (null == association) {
        throw new IllegalArgumentException("No such association found!");
    }

    studentDepartmentService.deleteAssociation(association);

    return new ResponseEntity<String>("success", HttpStatus.OK);

}

}` }`

the @RequestBody annotation helps you to make the json object into java object. @RequestBody注释可帮助您将json对象转换为java对象。

with this, you can take the payload as json, and get the java object and send the json back to the UI with ResponseEntity<Class> annotation 有了这个,您可以将有效负载作为json,并获取java对象并使用ResponseEntity<Class>注释将json发送回UI

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM