Coder Social home page Coder Social logo

spring-guides / gs-handling-form-submission Goto Github PK

View Code? Open in Web Editor NEW
44.0 20.0 84.0 1.3 MB

Handling Form Submission :: Learn how to create and submit a web form with Spring.

Home Page: https://spring.io/guides/gs/handling-form-submission/

License: Apache License 2.0

Java 74.32% HTML 18.43% Shell 7.26%

gs-handling-form-submission's Introduction

This guide walks you through the process of using Spring to create and submit a web form.

What You Will Build

In this guide, you will build a web form, which will be accessible at the following URL: http://localhost:8080/greeting

Viewing this page in a browser will display the form. You can submit a greeting by populating the id and content form fields. A results page will be displayed when the form is submitted.

Starting with Spring Initializr

You can use this pre-initialized project and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.

To manually initialize the project:

  1. Navigate to https://start.spring.io. This service pulls in all the dependencies you need for an application and does most of the setup for you.

  2. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.

  3. Click Dependencies and select Spring Web and Thymeleaf.

  4. Click Generate.

  5. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.

Note
If your IDE has the Spring Initializr integration, you can complete this process from your IDE.
Note
You can also fork the project from Github and open it in your IDE or other editor.

Create a Web Controller

In Spring’s approach to building web sites, HTTP requests are handled by a controller. These components are easily identified by the @Controller annotation. The GreetingController in the following listing (from src/main/java/com/example/handlingformsubmission/GreetingController.java) handles GET requests for /greeting by returning the name of a View (in this case, greeting). The following View is responsible for rendering the HTML content:

link:complete/src/main/java/com/example/handlingformsubmission/GreetingController.java[role=include]

This controller is concise and simple, but a lot is going on. The rest of this section analyzes it step by step.

The mapping annotations let you map HTTP requests to specific controller methods. The two methods in this controller are both mapped to /greeting. You can use @RequestMapping (which, by default, maps all HTTP operations, such as GET, POST, and so forth). However, in this case, the greetingForm() method is specifically mapped to GET by using @GetMapping, while greetingSubmit() is mapped to POST with @PostMapping. This mapping lets the controller differentiate the requests to the /greeting endpoint.

The greetingForm() method uses a Model object to expose a new Greeting to the view template. The Greeting object in the following code (from src/main/java/com/example/handlingformsubmission/Greeting.java) contains fields such as id and content that correspond to the form fields in the greeting view and are used to capture the information from the form:

link:complete/src/main/java/com/example/handlingformsubmission/Greeting.java[role=include]

The implementation of the method body relies on a view technology to perform server-side rendering of the HTML by converting the view name (greeting) into a template to render. In this case, we use Thymeleaf, which parses the greeting.html template and evaluates the various template expressions to render the form. The following listing (from src/main/resources/templates/greeting.html) shows the greeting template:

link:complete/src/main/resources/templates/greeting.html[role=include]

The th:action="@{/greeting}" expression directs the form to POST to the /greeting endpoint, while the th:object="${greeting}" expression declares the model object to use for collecting the form data. The two form fields, expressed with th:field="{id}" and th:field="{content}", correspond to the fields in the Greeting object.

That covers the controller, model, and view for presenting the form. Now we can review the process of submitting the form. As noted earlier, the form submits to the /greeting endpoint by using a POST call. The greetingSubmit() method receives the Greeting object that was populated by the form. The Greeting is a @ModelAttribute, so it is bound to the incoming form content. Also, the submitted data can be rendered in the result view by referring to it by name (by default, the name of the method parameter, so greeting in this case). The id is rendered in the <p th:text="'id: ' + ${greeting.id}" /> expression. Likewise, the content is rendered in the <p th:text="'content: ' + ${greeting.content}" /> expression. The following listing (from src/main/resources/templates/result.html) shows the result template:

link:complete/src/main/resources/templates/result.html[role=include]

For clarity, this example uses two separate view templates for rendering the form and displaying the submitted data. However, you can use a single view for both purposes.

Make the Application Executable

Although you can package this service as a traditional WAR file for deployment to an external application server, the simpler approach is to create a standalone application. You package everything in a single, executable JAR file, driven by a good old Java main() method. Along the way, you use Spring’s support for embedding the Tomcat servlet container as the HTTP runtime, instead of deploying to an external instance. The following listing (from src/main/java/com/example/handlingformsubmission/HandlingFormSubmissionApplication.java) shows the application class:

link:complete/src/main/java/com/example/handlingformsubmission/HandlingFormSubmissionApplication.java[role=include]

Logging output is displayed. The service should be up and running within a few seconds.

Test the service

Now that the web site is running, visit http://localhost:8080/greeting, where you see the following form:

Form

Submit an ID and message to see the results:

Result

Summary

Congratulations! You have just used Spring to create and submit a form.

gs-handling-form-submission's People

Contributors

bclozel avatar benjaminherbert avatar boykoalex avatar btalbott avatar cbeams avatar gregturn avatar martinlippert avatar petrsponer avatar robertmcnees avatar royclarkson avatar sdeleuze avatar spring-operator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gs-handling-form-submission's Issues

Upgrade Spring Boot to the latest version

Update the guide to use the most recent Spring Boot version.

To do so, change the Spring Boot version in:

initial/build.gradle
initial/pom.xml
complete/build.gradle
complete/pom.xml

Update the Spring Boot version

Update the guide to use the most recent Spring Boot version.

To do so, update the Spring Boot version in:

initial/build.gradle
initial/pom.xml
complete/build.gradle
complete/pom.xml

Feature request: An advanced form submission example

It would be nice to see an example of an advance form submission. We recently were working on a project that had a form that looked like this:

//example: for each $post in $posts
<li>
  <input name="post[$postId][title]" value="$post.title" />
</li>

We really struggled with the appropriate way to structure a controller request model that Spring WebMVC would bind to. Maybe help there is a guide, and maybe also it is improvement to the documentation on html form binding.

I tried to fix some typos

in the text. But was not able to make a pull request.

2 asteriks are not properly escaped in the text.

unable to call web application from the spring boot to send params through url.

I am try to using Angularjs2 with spring boot application every thing working fine with the small issue.

Description:

step1. if we have default router like router('') meaning localhost:8080/ it is calling index.html page with out having issues.

step2. if we have added context path like router('accountsummary') meaning localhost:8080/accountsummary its not working. when i give like below configuration in spring boot conf like below:

@configuration
public class WebController extends WebMvcConfigurerAdapter{
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/accountSummary").setViewName("index.html");
}
}

it was working fine.

  1. when i want to configure like route('accountsummary/:reqid). reqid is the parameter meaning i want to call like localhost:8080/accountsummary/abc it is not working. i have given like (/**)

@configuration
public class WebController extends WebMvcConfigurerAdapter{
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/accountSummary/**").setViewName("index.html");
}
}

its not working and giving like below:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Jun 30 15:11:38 EDT 2016
There was an unexpected error (type=Not Found, status=404).
No message available

Can any one pleae help me out

Conflict with Thymeleaf's th:insert

This isn't a "bug" with this tutorial per-se, but rather a gotcha that I was trying to solve which led me to this tutorial in an effort to figure out what I was doing wrong. If this should not be recorded here, please suggest another place to put it.

Problem: Certain Thymeleaf expressions seem to cause the page to only partially load.
Solution: Add the following to the application configuration (ie: application.properties")
spring.thymeleaf.servlet.produce-partial-output-while-processing=false

In my case, my template was taking advantage of the th:replace and th:insert attributes.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="https://www.thymeleaf.org">

  <head th:replace="~{'fragments/headTagFragment'}"><title>Will Be Replaced</title></head>
  <body>
    <div th:replace="~{'fragments/navigation'}"></div>
    <form th:action="@{/contact}" th:object="${contactMessageDTO}" method="POST">
      <!-- boilerplate contact form -->
    </form>
    <div th:replace="~{'fragments/footer'}"></div>
  </body>
</html>

Experience:

  • When I inspected the page in the browser, I had the HTML tags and the HEAD tags, but the headTagFragment would only be partially rendered, and the degree of rendering was random.
  • The error messaging indicated a problem with the th:action in my form tag. This sent me down a rabbit hole looking for why the /contact endpoint could not be found.
  • When I removed the th:action the page would load (but of course, it would not have anywhere to submit to).
  • If I commented out my navigation fragment, the page would load (but it would not look as designed).

Setting the produce-partial-output-while-processing to false, forced the page to be fully created before rendering in the browser. That seems to have been key.

greetingSubmit method is quite confusing

In this project, the following code lead me to a great misunderstanding, I want to share it, and maybe I can help others.

// GreetingController.java
 @PostMapping("/greeting")
    public String greetingSubmit(@ModelAttribute Greeting greeting) {
        return "result";
    }

// result.html
<p th:text="'content: ' + ${greeting.content}"/>

At first glance in the result.html, I thought greeting object may refer to the @ModelAttribute Greeting greeting, then I tried to make some modification to use another model OtherModel, but it turned out to be exception.
After google quite a while, I found out that here the ${greeting.content} is linked to the name of the model class rather than the name of the key.
So I believe that the proper way to do this is like this.

    @PostMapping("/greeting2")
    public String greetingSubmit(@ModelAttribute OtherModel greeting, Model model) {
        model.addAttribute("greeting", greeting);
        return "result";
    }

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.