简体   繁体   中英

How to insert data into database after creating JSON from “HTML form” with POSTMAPPING in spring boot?

I am trying to insert data to my jdbc h2 database after getting information from "html form" and converting to json. I was using swagger earlier to Read/Write data and that works perfectly. That's why I converted "HTML form" info to "json". Now, I am trying to use HTML to show my webpages and Read/Write data from database. The code is down below. Do I need to change my code structure?

This is the school.java file

@Getter
@Setter
public class School extends BaseModel{
    private String schoolName;
    private String schoolEmail;
    private String schoolStreet;
    private String schoolHouse;
    private String schoolCity;
    private String schoolState;
    private String schoolCountry;
    Long schoolPhone;
    Long schoolZip;
    private String image;
    private String status;
}

This is the rowMapper for database

public class SchoolDaoRowMapper extends BaseRowMapper<School> {

    public enum SchoolColumnType {
        SCHOOL_NAME, SCHOOL_EMAIL, SCHOOL_STREET, SCHOOL_HOUSE,
        SCHOOL_ZIP, SCHOOL_CITY, SCHOOL_STATE, SCHOOL_COUNTRY, SCHOOL_PHONE,
        STATUS, IMAGE;
        private String columnName;
        SchoolColumnType() {
            columnName = name().toLowerCase();
        }
        public String getColumnName() { return columnName; }
    }

    @Override
    public Map<String, Object> mapObject(@NotNull School school) {
        Map <String,Object> map = new HashMap<>();
        map.put(ID.getColumnName(), school.getId());
        map.put(SCHOOL_EMAIL.getColumnName(),school.getSchoolEmail());
        map.put(SCHOOL_NAME.getColumnName(),school.getSchoolName());
        map.put(SCHOOL_STREET.getColumnName(),school.getSchoolStreet());
        map.put(SCHOOL_HOUSE.getColumnName(),school.getSchoolHouse());
        map.put(SCHOOL_ZIP.getColumnName(),school.getSchoolZip());
        map.put(SCHOOL_CITY.getColumnName(),school.getSchoolCity());
        map.put(SCHOOL_STATE.getColumnName(),school.getSchoolState());
        map.put(SCHOOL_COUNTRY.getColumnName(),school.getSchoolCountry());
        map.put(SCHOOL_PHONE.getColumnName(),school.getSchoolPhone());
        map.put(STATUS.getColumnName(),school.getStatus());
        map.put(IMAGE.getColumnName(),school.getImage());
        map.put(CREATED_BY.getColumnName(), school.getCreatedBy());
        map.put(UPDATED_BY.getColumnName(), school.getUpdatedBy());
        map.put(CREATED_DATE.getColumnName(), javaTimeFromDate(school.getCreatedDate()));
        map.put(UPDATED_DATE.getColumnName(), javaTimeFromDate(school.getUpdatedDate()));
        return map;
    }

    @Override
    public School mapRow(ResultSet rs, int rowNum) throws SQLException {
        School school = new School();
        
        school.setId(rs.getLong(ID.getColumnName()));
        school.setSchoolName(rs.getString(SCHOOL_NAME.getColumnName()));
        school.setSchoolEmail(rs.getString(SCHOOL_EMAIL.getColumnName()));
        school.setSchoolStreet(rs.getString(SCHOOL_STREET.getColumnName()));
        school.setSchoolHouse(rs.getString(SCHOOL_HOUSE.getColumnName()));
        school.setSchoolZip(rs.getLong(SCHOOL_ZIP.getColumnName()));
        school.setSchoolCity(rs.getString(SCHOOL_CITY.getColumnName()));
        school.setSchoolState(rs.getString(SCHOOL_STATE.getColumnName()));
        school.setSchoolCountry(rs.getString(SCHOOL_COUNTRY.getColumnName()));
        school.setSchoolPhone(rs.getLong(SCHOOL_PHONE.getColumnName()));
        school.setStatus(rs.getString(STATUS.getColumnName()));
        school.setImage(rs.getString(IMAGE.getColumnName()));
        school.setCreatedBy(rs.getLong(CREATED_BY.getColumnName()));
        school.setUpdatedBy(rs.getLong(UPDATED_BY.getColumnName()));
        school.setCreatedDate(dateFromJavaTime(rs.getObject(CREATED_DATE.getColumnName())));
        school.setUpdatedDate(dateFromJavaTime(rs.getObject(UPDATED_DATE.getColumnName())));
        return school;
    }
}

This is the dao file that inserts data to the database.

@Override
    public School create(School school, Long creatorId) {
        if (school == null) {
            throw new DaoException("Request to create a new school received null values.");
        } else if (school.getId() != null) {
            throw new DaoException("When creating a new school the id should be null, but was set to " + school.getId());
        }
        LOG.trace("School Dao creating user {}", school);

        school.setStatus("ACTIVE");
        school.setCreatedDate(LocalDateTime.now());
        school.setUpdatedDate(LocalDateTime.now());
        KeyHolder keyHolder = new GeneratedKeyHolder();
        int result = this.jdbcTemplate.update(sql("createSchool"), //This maps the data to database. The "createSchool" is SQL STATEMENT that executes INSERT INTO command.
                new MapSqlParameterSource(rowMapper.mapObject(school)), keyHolder, new String[]{BaseRowMapper.BaseColumnType.ID.name()});

        if (result != 1) {
            throw new DaoException(String.format("SchoolDao: Failed attempt to create user %s - affected %s rows", school.toString(), result));
        }

        @CheckForNull //Createa a ID values for database
        Long id = keyHolder.getKey().longValue();
        school.setId(id);


        return school;
    }

This is the controller

@Controller
public class SchoolRestController {

    public static final String BASE_SCHOOL_PATH = "/School";
    public static final String GET_EMAIL_PATH = BASE_SCHOOL_PATH + "/email";
    public static final String DELETE_USER_PATH = BASE_SCHOOL_PATH + "/delete";

    private final SchoolDao schoolDao;

    private static final Logger logger = LoggerFactory.getLogger(SchoolRestController.class);

    @Autowired
    public SchoolRestController(SchoolDao schoolDao){this.schoolDao = schoolDao;}

    //Manage School Page
    @GetMapping ("/ManageSchool")
    public String manageSchoolPage(Model model){
        return "manageSchool";
    }

    // Create school page
    @GetMapping(BASE_SCHOOL_PATH+"/Create")
    public String createSchoolForm(Model model){
        model.addAttribute("school",new School());
        return "createSchoolForm";
    }

    @ApiOperation(value = "Create School")
    @PostMapping(value = BASE_SCHOOL_PATH+"/Create")
    public String create (School school, @ApiIgnore HttpServletResponse response) throws IOException {
        // components tests are expecting this assertion and exception handling, and will fail if removed
        try {
            Assert.isNull(school.getId(), "School ID field must be null");
            Assert.notNull(school.getSchoolEmail(),"School email cannot be null.");
            Assert.isNull(schoolDao.readByEmail(school.getSchoolEmail()),"School already exists in the system.");
            schoolDao.create(school, null);// This should create the School item in DATABASE from the DAO.create
        } catch (IllegalArgumentException e) {
            logger.error(e.getMessage(), e);
            response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, e.getMessage());
            return null;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            return null;
        }
        return "createSchoolForm";
    }

Here is the HTML file to create a new school. Giving all these null values so that it makes a JSON format for the ROW mapper to map properly.

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <title>Create School || EDUBD</title>
    <meta charset="utf-8">
</head>
<body>
    <h1>EDUBD - Manage School Portal</h1>

    <h3>Create New School</h3> <br>

    <form action="#" th:action="@{/School/Create}" th:object="${school}" th:method="POST">
        <label>School Name:<br>
        <input type="text" th:field="*{schoolName}" id="schoolName" required>
        </label> <br>
        <label>School Email:<br>
        <input type="text" th:field="*{schoolEmail}" id="schoolEmail" required>
        </label> <br>
        <label>Phone Number: <br>
        <input type="tel" th:field="*{schoolPhone}" id="schoolPhone" required>
        </label> <br>
        <input id='btn' type="submit" value="Submit" > <input type="reset" value="Reset"/>
    </form>

    <div id="msg">
        <pre></pre>
    </div>

    <script>
        let schools=[];
        const addSchool = (ev) =>{ //ev=event
            ev.preventDefault();
            let school={ //create a json object
                schoolName: document.getElementById('schoolName').value,
                schoolEmail: document.getElementById('schoolEmail').value,
                schoolPhone: document.getElementById('schoolPhone').value,
                status: null,
                schoolStreet:null,
                SchoolHouse:null,
                schoolZip:null,
                schoolCity:null,
                schoolState:null,
                schoolCountry:null,
                image:null,
                createBy:null,
                updatedBy:null,
                createdDate:null,
                updatedDate:null,
                id:null
            }
            schools.push(school);
            document.forms[0].reset(); // clear the form.

            //display only
            console.warn('added',{schools});

            let pre=document.querySelector('#msg pre');
            pre.textContent= '\n'+ JSON.stringify(schools,'\t',2);
        }

        document.addEventListener('DOMContentLoaded',() =>{
            document.getElementById('btn').addEventListener('click',addSchool);
        })
    </script>

Here is the table

CREATE TABLE schools (
    id BIGINT(20) AUTO_INCREMENT PRIMARY KEY,
    school_name VARCHAR(255) NOT NULL,
    school_email VARCHAR(255) UNIQUE NOT NULL,
    school_street VARCHAR(255),
    school_house VARCHAR(255),
    school_zip BIGINT(10),
    school_city VARCHAR(255),
    school_state VARCHAR(255),
    school_country VARCHAR(255),
    school_phone BIGINT(20),
    status VARCHAR(255) NOT NULL,
    image VARCHAR(255),
    created_by BIGINT(20) NULL,
    created_date BIGINT(20) NOT NULL,
    updated_date BIGINT(20) DEFAULT NULL,
    updated_by BIGINT(20) NULL
);

The solution that worked for me.

I have redesigned the HTML to send data with XMLHttpRequest() function. My DAO() works when I sent data with xhr.send() . @RequestBody captured the data. Also, I added produces and consumes to my controller.

The new HTML:

 <h3>Create New School</h3> <br>
    <form id="createSchool" method="post">
        <br>
        <label>School Name:
        <input type="text" id="schoolName"  value="" required/>
        </label>
        <br>
        <label>School Email:
        <input type="email" id="schoolEmail" value="" required/>
        </label>
        <br>
        <label>School Phone Number:
        <input type="tel" id="schoolPhone" value="" required/>
        </label>
        <br>
        <button type="button" id="submit">Submit Form</button>
    </form>

    <div id="feedback"></div>

    <script>
        $(document).ready( function() {
            $("#submit").click(function(e) {
                e.preventDefault();
                var school=new Object();
                school.schoolName = $("#schoolName").val();
                school.schoolEmail= $("#schoolEmail").val();
                school.schoolPhone = $("#schoolPhone").val();
                school.status= null;
                school.schoolStreet= null;
                school.schoolHouse= null;
                school.schoolZip= null;
                school.schoolCity= null;
                school.schoolState= null;
                school.schoolCountry= null;
                school.image= null;
                school.createBy= null;
                school.updatedBy= null;
                school.createdDate= null;
                school.updatedDate= null;
                school.id= null;

                var s2=JSON.stringify(school);
                console.log(s2);

                var xhr = new XMLHttpRequest();
                xhr.open("POST", "SchoolCreate",true);
                xhr.setRequestHeader("Content-Type", "application/json");
                xhr.onreadystatechange = function() { // Call a function when the state changes.
                    if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
                        // Request finished. Do processing here.
                        console.log("success");
                        $('#feedback').html("Success");
                    }
                    else {
                        console.log(xhr.responseText);
                        $('#feedback').html(xhr.responseText);
                    }
                }
                xhr.send(s2);
                // this makes the form empty after submission. 
                document.getElementById('schoolName').value='';
                document.getElementById('schoolEmail').value='';
                document.getElementById('schoolPhone').value='';


            });
        });
    </script>

</body>

The controller

@ApiOperation(value = "Create School")
    @PostMapping(value = "/ManageSchool"+BASE_SCHOOL_PATH+"/SchoolCreate", produces = {"application/json"},
            consumes = {"application/json"})
    public String create (@RequestBody School school, @ApiIgnore HttpServletResponse response) throws IOException {
        // components tests are expecting this assertion and exception handling, and will fail if removed
        try {
            Assert.isNull(school.getId(), "School ID field must be null");
            Assert.notNull(school.getSchoolEmail(),"School email cannot be null.");
            Assert.notNull(school.getSchoolPhone(),"School Phone number cannot be null. ");
            Assert.isNull(schoolDao.readByEmail(school.getSchoolEmail()),"School already exists in the system.");
            schoolDao.create(school, null);
            return "createSchoolForm";
        } catch (IllegalArgumentException e) {
            logger.error(e.getMessage(), e);
            response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, e.getMessage());
            return null;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            return null;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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