My whole HTML/JSP is pretty standard with JSTL tags to help with databinding while I send off JSON via JS. Submit the form data as JSOn via Fetch and off it goes to the controller with @RequestBody annotations and a RedirectAttributes redirect. Every part of my layers within the application is working as it needs to. DTO, Service, Exceptions and so on. Once I actually try to addFlashAttributes to redirect to another URL, I get status code 400.
I’m going to start with my HTML/JSP, JS for the form data, show the configuration I have so far in my Servlet config class, and the controller. Then show the result page and the JS script src.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title> Ken </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
<meta name="description" content="Kenneth's thingy">
<meta name="author" content="Kenneth Steven Lee">
<link rel="stylesheet" type="text/css" href="/untitled2/URLtoResources/css/stuff.css">
<script type="text/javascript" src="/untitled2/URLtoResources/javascript/stuff.js" defered></script>
</head>
<body>
<h2> Please post student here </h2>
<form:form name="getForm" action="postStudent" modelAttribute="student_guy" id="studentForm" method="post" enctype="multipart/form-data
<p>
<form:input path="id" type="number" autocomplete="off" id="first" /> <form:errors path="id" /> </p>
<p>
<form:input path="name" type="text" autocomplete="off" id="second" /> <form:errors path="name" /></p>
<p>
<form:input path="mobile" type="number" autocomplete="off" id="third" /> <form:errors path="mobile" /></p>
<p>
<form:input path="country" type="text" autocomplete="off" id="fourth" /> <form:errors path="country" /></p>
<input type="submit" value="submit" id="studentFormThing" />
</form:form>
</body>
</html>
"use script"
window.addEventListener("load", () =>
{
const form_Issue = document.forms["getForm"];
async function postData(form_Issue)
{
try
{
const formData = new FormData(form_Issue);
const thing = Object.fromEntries(formData);
console.log(JSON.stringify(thing));
const response = await fetch("/untitled2/something/postStudent", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(thing)
});
const result = response.json();
console.log("the shit is going " + result);
}
catch (e)
{
console.error(e);
}
}
form_Issue.addEventListener("submit", (event) => {
postData(form_Issue);
})
})
package org.ken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.ken.Service.StudentServiceImpl;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import org.hibernate.validator.internal.util.stereotypes.Lazy;
import org.ken.Model.Student;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
@RequestMapping("/something")
public class WebController {
@Autowired
ObjectMapper objectmapper;
@Autowired
StudentServiceImpl student_service;
@GetMapping("/studentpost")
public String getStudent(@ModelAttribute("student_guy") Student student_guy, Model model)
{
model.addAttribute("student_guy", student_guy);
return "index";
}
@PostMapping(value = "postStudent", consumes = {"application/json", "multipart/form-data"})
public String postStudent(@RequestBody String student_guy_two, BindingResult error, RedirectAttributes redirect) throws JsonMappingException, JsonProcessingException
{
Student student_guy_three = objectmapper.readValue(student_guy_two, Student.class);
if (error.hasErrors())
{
return "error";
}
student_service.insert(student_guy_three);
redirect.addFlashAttribute(student_guy_three);
return "redirect:/something/student";
}
@GetMapping(value = "/student")
public String getList(@ModelAttribute("student_guy") Student student_guy, Model model)
{
List<Student> test_list = /**/student_service.getStudent();
model.addAttribute("student", test_list);
return "result";
}
}
package org.ken;
import jakarta.servlet.ServletContext;
import jakarta.servlet.annotation.MultipartConfig;
import org.apache.commons.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
@Configuration
@EnableWebMvc
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan("org.ken")
public class WebServletInit implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
@Bean MappingJackson2JsonView jsonView()
{
MappingJackson2JsonView js = new MappingJackson2JsonView();
js.setPrettyPrint(true);
return js;
}
@Bean
public ViewResolver contentNegotiationViewResolver(ContentNegotiationManager manager)
{
ContentNegotiatingViewResolver viewresolver = new ContentNegotiatingViewResolver();
viewresolver.setContentNegotiationManager(manager);
List<View> views = new ArrayList<>();
views.add(new MappingJackson2JsonView());
viewresolver.setDefaultViews(views);
return viewresolver;
}
@Bean
@Primary
public ObjectMapper objectMapper() {
final ObjectMapper mapper = new ObjectMapper();
return mapper;
}
@Bean
public MappingJackson2HttpMessageConverter objectMapper1(){
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
converter.setObjectMapper(builder.build());
return converter;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer config)
{
config.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
VersionResourceResolver versionResolver = new VersionResourceResolver().addContentVersionStrategy("/**");
ResourceHandlerRegistration resourceRegistration = registry.addResourceHandler("/URLtoResources/**").addResourceLocations("/resources/");
}
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public DataSource dataSource()
{
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUsername("root");
dataSource.setPassword("REVOLVEr10101!");
dataSource.setUrl("jdbc:mysql://localhost:3306/school?allowPublicKeyRetrieval=true&useSSL=false");
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
return dataSource;
}
@Bean(name = "applicationJdbcTemplate")
public JdbcTemplate applicationDataConnection(){
return new JdbcTemplate(dataSource());
}
@Bean
public TransactionManager transactionManager(DataSource dataSource)
{
return new DataSourceTransactionManager(dataSource);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title> Ken </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
<meta name="description" content="Kenneth's thingy">
<meta name="author" content="Kenneth Steven Lee">
<script type="text/javascript" src="/untitled2/URLtoResources/javascript/stufftwo.js" defered></script>
</head>
<body>
<h1> Big pimpin </h1>
${student}
<br>
<c:forEach var="guy" items="${student}">
${guy}
<br>
</c:forEach>
</body>
</html>
"use strict"
window.addEventListener("load", () =>
{
})
At this point, all I was expecting was just for JSON to data bind with Object Mapper and send off the instance of the class with redirection via addFlashAttribute(student_guy_three). I wanted everything added into the database with a clean redirection with all the list of java object. ALl I get back is status code 400.