HTTP Status 400 - Spring MVC Error - java

I´m developing a webapp with Maven and Spring MVC. When submitting a button the HTTP Status 400- Error appears. The descriptions says: "The request sent by the client was syntactically incorrect."
This is my .jsp:
<body>
<form:form modelAttribute="circleUpForm" method="POST" action="" enctype="multipart/form-data">
<!-- path gibt den Namen der member Variablen an -->
Input-File (.pdf): <form:input path="file" type="file"/><br />
<input type="submit" value="Start Circle Up">
</form:form>
</body>
And this are the relevant methods of my Controller:
#RequestMapping(value = "/CircleUp", method = RequestMethod.GET)
public String circleUpGet(Model model) {
CircleUpForm circleUpForm = new CircleUpForm();
model.addAttribute("circleUpForm", circleUpForm);
// Eine einzelne .jsp wird returnt
return "CircleUp";
}
// POST: CircleUp
#RequestMapping(value = "/CircleUp", method = RequestMethod.POST)
public String circleUpPost(HttpServletRequest request, Model model, //
#ModelAttribute("circleUpForm") CircleUpForm circleUpForm) {
return this.doUpload(request, model, circleUpForm);
}
This is my Form:
import org.pdfclown.files.File;
public class CircleUpForm {
// private CommonsMultipartFile file;
// File
private File file;
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
}
The GET method works well, but when clicking on the submit button on my view the error appears. Thus I think something went wrong on my POST Method. I tried to debug the problem but not even the method is executed. I have just started programming with Spring MVC and I´m not really familiar with some concepts. Maybe someone has an idea? Thank you !

Remove the "enctype="multipart/form-data" tag from your .jsp.

Related

Spring MVC file upload is passing null to the controller

i've a spring MVC application and when i try to upload a multipart file, a null value is passed to the controller. all the other text parameters are passed properly only the file input is passed as null. I've included the MultipartResolver bean and commons-io plus commons-fileupload dependencies in my project. i've checked it's passed in the browser's request but it's not bound in the modelAttribute.
here is a snippet code from my view
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity" commandName="profileModel">
<span><b>Upload your passport photo</b></span>
<form:input path="passportPhotograph" type="file" id="passportPhoto"/>
</form:form>
and here is a snippet from my controller method
#RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST)
public ModelAndView saveIdentity(#ModelAttribute("profileModel") #Valid ProfileModel profileModel,HttpServletRequest request){
MultipartFile photo = profileModel.getPassportPhotograph();
if(photo != null){ do something.... }
}
here is my ProfileModel.java class snippet
public class ProfileModel{
private MultipartFile passportPhotograph;
public MultipartFile getPassportPhotograph() {
return passportPhotograph;
}
public void setPassportPhotograph(MultipartFile passportPhotograph) {
this.passportPhotograph = passportPhotograph;
}
............
}
And in my dispatcher-servlet file I have declared MultipartResolver bean:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="99999999999"/>
</bean>
and finally in my build.gradle file i added these dependencies
compile('commons-io:commons-io:2.0.1')
compile('commons-fileupload:commons-fileupload:1.3.1')
after all this it's passing null to my controller even though it's included in the HttpServletRequest. what should i do to fix this. Thanks in advance for you help.
you need to use #RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST, headers = ("content-type=multipart/*"), produces = "application/json", consumes = "image/*").
Solved my issue by using the StandardServletMultipartResolver which comes with the spring web framework. But you have to use Servlet version 3.0+ for this to work.
This sample code. point is input tag name binding file in model. maybe you need library json and file. ex) commons-io, commons-fileupload and jackson, gson use to parsing in controller.
HTML
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity">
<span><b>Upload your passport photo</b></span>
<form:input type="file" name="file"/>
</form:form>
Controller
#RequestMapping(value = "test", method = RequestMethod.POST)
public String testFormData(FileAndContentModel model) {
// break point and check model.
return "success";
}
Model
public class FileAndContentModel {
private MultipartFile file;
public FileAndContentModel () {
}
// getter, setter
}
This is not the solution, I just type here because is easier to read than a comment. Please try the minimum requeriment, just upload a file and verify if works.
Form:
<form:form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/profile/secure/saveIdentity">
<span><b>Upload your passport photo</b></span>
<input name="file" type="file" id="passportPhoto"/>
</form:form>
Controller:
#RequestMapping(value = "/secure/saveIdentity", method = RequestMethod.POST)
public void saveIdentity(#RequestParam("file") MultipartFile file) {
//please verify here if the file is null

How to retrieve input text from thymeleaf?

I am trying to get a value from thymeleaf input into my java class.
Simple script from thymeleaf
<h1>Form</h1>
<form action="#" th:action="#{index}" th:object="${emails}" method="post">
<p>Emails: <input id="emailbox" type="text" th:field="*{email}"
placeholder="Enter e-mails: eg; Foo#gmail.com, Bar#yahoo.com"/></p>
<p><input type="submit" value="Submit"/> <input type="reset" value="Reset"/></p>
</form>
How would I be able to retrieve the inputted text into my java class?
Controller
#Controller
public class IndexController {
#RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView getdata() throws IOException {
ModelAndView model = new ModelAndView("index");
model.addObject("emails", new MailModel());
return model;
}
#PostMapping("/index")
public String emailSubmit(#ModelAttribute MailModel emails) {
System.out.println(emails.getEmail());
return "index";
}
I am able to run my application and see thymeleaf view. When I enter some text into the text box and hit submit. I receive an error.
Error Message
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'emails' available as request attribute
My Application is created with Springboot, Java, and Thymeleaf. What am I doing wrong? Is it possible that ModelandView does not work with PostMapping? I also followed https://spring.io/guides/gs/handling-form-submission/ and I got that sample working, but when I tried to follow the logic and implement into my project. It did not work.
In your HTML, change th:action="#{index}" to th:action="#{/index}". This will allow Thymeleaf to resolve it properly.

Spring MVC multipart/form-data file upload then go to a jsp page

I had a working form submit on a jsp that takes some basic info as strings. The controller validates the user inputs and determines if it should go back to the page to display error msg or go to a new page. Then I modified the form submit to allow users to upload files. The problem is when I return the String in my controller method, it doesn't go to the right jsp pages anymore. It just goes to a blank page with text of "/ad/adAdd3/12345" or "redirect:/ad/adDetail/12345". What am i missing?
jsp:
<form:form modelAttribute="ad" method="post" class="form-horizontal" autocomplete="off" id="add-ad-form"
action="?${_csrf.parameterName}=${_csrf.token}" enctype="multipart/form-data">
controller:
#RequestMapping(value = "/ad/adAdd3/{categoryId}", method = RequestMethod.POST)
public #ResponseBody String postAdAdd(#RequestParam("categoryId") int categoryID,
#ModelAttribute("ad") #Valid Ad ad,
BindingResult aaResult,
SessionStatus aaStatus, Principal aaPrincipal) {
if (aaResult.hasErrors()) {
return "/ad/adAdd3/" + categoryID;
} else {
ad = this.caService.saveAd(ad, categoryID,
((UserDetailsImpl) ((Authentication) aaPrincipal)
.getPrincipal()).getUser());
aaStatus.setComplete();
return "redirect:/ad/adDetail/" + ad.getId();
}
}
#ResponseBody is the problem. Once I removed it, everything is working now.

Uploading files in Spring with Tomcat related to the maximum size allowed

I am considerably new with Spring, and I want to have a multipart form and handle the MaxUploadSizeExceededException exception in order to show an error message in the jsp. The main problem I have is the ModelAndView Object in the class MaxUploadSizeLimitExceededExceptionResolver, that I don't know how to use it for such objective previously explained.
Files that I have:
1) Model class UploadItem.java. 2) View form UploadForm.jsp. 3) Controller Uploadcontroller.java. 4) Class MaxUploadSizeLimitExceededExceptionResolver.java to handle the exception Uploadcontroller
1) Model UploadItem
public class UploadItem {
private String name;
private CommonsMultipartFile fileData;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public CommonsMultipartFile getFileData() {
return fileData;
}
public void setFileData(CommonsMultipartFile fileData) {
this.fileData = fileData;
}
}
2) View form UploadForm.jsp
<html>
<head>
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Upload form</title>
</head>
<body>
<form:form modelAttribute="uploadItem" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Upload Fields</legend>
<p>
<form:label for="name" path="name">Name</form:label><br/>
<form:input path="name"/>
</p>
<p>
<form:label for="fileData" path="fileData">File</form:label><br/>
<form:input path="fileData" type="file"/>
</p>
<p>
<input type="submit" />
</p>
</fieldset>
</form:form>
</body>
</html>
3) Controller Uploadcontroller
public class Uploadcontroller {
#RequestMapping(method = RequestMethod.GET)
public String getUploadForm(Model model) {
model.addAttribute(new UploadItem());
return "upload/uploadForm";
}
#RequestMapping(method = RequestMethod.POST)
public String create(HttpServletRequest request, UploadItem uploadItem,
BindingResult result, Exception exception) {
if (result.hasErrors()) {
// logger.info("create upload");
for (ObjectError error : result.getAllErrors()) {
System.err.println("Error: " + error.getCode() + " - "
+ error.getDefaultMessage());
}
return "upload/uploadForm";
}
System.err.println("Test upload: " + uploadItem.getName());
System.err.println("Test upload: "
+ uploadItem.getFileData().getOriginalFilename());
// TODO redirect this
return "/home";
}
}
4) Component to handle the exception Uploadcontroller
#Component
public class MaxUploadSizeLimitExceededExceptionResolver extends
SimpleMappingExceptionResolver {
private static final Logger logger = LoggerFactory
.getLogger(HomeController.class);
#Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception exception) {
Map<String, Object> model = new HashMap<String, Object>();
logger.info("getUploadForm at the beggining");
ModelAndView modelView = new ModelAndView();
if (exception instanceof MaxUploadSizeExceededException)
{
model.put("errors", exception.getMessage());
modelView.addObject("errors", exception.getMessage());
logger.info("getUploadForm: MaxUploadSizeExceededException" );
} else
{
model.put("errors", "Unexpected error: " + exception.getMessage());
modelView.addObject("errors", "Unexpected error: " +exception.getMessage());
}
logger.info("getUploadForm at the end" );
model.put("uploadedFile", new UploadItem());
modelView.addObject(new UploadItem());//("uploadedFile", new UploadItem());
modelView.setViewName("/upload/uploadForm");
return modelView;
}
}
Edit to add more details:
Actually, the problem is in another direction. The size of my maxUploadSize file was set to 1MB, but I was trying to do tests with files bigger than 3 MB. When I try with a file until 2 MB maximum is working fine. The problem is that I get a ERR_CONNECTION_RESET and it seems something related to Tomcat, a config of maxSwallowSize --> stackoverflow.com/questions/29113262/… I will continue researching and keep this thread updated.
New information.
I have tried with Tomcat 7.0.61 and the error is ERR_CONNECTION_ABORTED
I have tried with Tomcat 6.0.43 and there is no error!
After investigating, the problem was due to Tomcat.In the version 7.0.55 was introduced the property maxSwallowSize set by default to 2MB. This made Tomcat to abort the upload request. By setting this attribute to another value the problem is solved (I changed it to -1, please do not do that in your PRD environment as Tomcat will really try to get a X MB file to upload). I did this by adding in my Tomcat server file ${tomcat_dir}/conf/server.xml in my connector property the attribute maxSwallowSize
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxSwallowSize="-1"/>
You need to restart Tomcat so it takes this configuration, if does not work, delete the server and add it again.

How to have multiple buttons and treat them accordingly in a Spring MVC form?

By using Spring MVC + Maven + Hibernate I'm trying to build a Spring MVC form that has both an "Add To Cart" button, as well as a "Add to Favourites" button. Whenever one button is pressed, the other one returns null as shown in the code below.
Both buttons are type=submit and I'm treating them in the code below. The problem I'm having is that the "Add to Favourites" case is always resulting into an uncaught exception (redirecting me to the "Internal Error" page).
I'm wondering if maybe there's an elegant way to treat each button press in a form separately, without having lots of if - statements for each button.
The HTML file has the following items declared in the form's structure:
<c:if test="${empty readOnly}">
<input type="number" value="1" name="quantity" class="input-mini"/>
<button class="btn btn-primary" type="submit" name="addToCart"><i class="icon-shopping-cart icon-white"><jsp:text /></i> Add</button>
<button class="btn btn-secondary" type="submit" name="favourite"><jsp:text /> Favourite This!</button>
</c:if>
And I'm using the following Controller method:
#RequestMapping(value = "/submit", method = RequestMethod.POST, produces = "text/html")
public String submit(HttpServletRequest request, Model uiModel) {
init(uiModel);
String id = request.getParameter("product-id");
String quantity = request.getParameter("quantity");
if(!request.getParameter("addToCart").toString().equals(null))
{
if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(quantity)) {
shoppingCartServiceLocal.addToShoppingCart(shoppingCart, id, quantity);
}
}
if(!request.getParameter("favourite").equals(null))
{
//ADD TO FAVOURITE
}
return "redirect:/items/" + id;
}
I might be missing something obvious as I'm still learning these. Any help would be greatly appreciated.
Use the param attribute to specify which method to use for which button.
#RequestMapping(value = "/submit", method = RequestMethod.POST, params = "addToCart")
public String addToCart(HttpServletRequest request, Model uiModel) {
//your code
}
#RequestMapping(value = "/submit", method = RequestMethod.POST, params = "favourite")
public String addToFavorites(HttpServletRequest request, Model uiModel) {
//your code
}

Categories