0

I am new to spring and am trying to pass a string value via radio button in a form to a controller, then to a view. I can do it with no problem if the controller @RequestParam type is string. But what I want to do next is map the radio button attrib value to an object such as:

@Component
public class ChoiceBean {
    private String choice;

    public String getChoice() {
        return choice;
    }

    public void setChoice(String choice) {
        this.choice = choice;
    }

    @Override
    public String toString() {
        return "ChoiceBean{" + "choice=" + choice + '}';
    }
}

...but it returns null in the view. What am I doing wrong?

I used this to update my controller methods getChoice() & processChoiceGet().

Here are my files:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
            http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>flashcards-springboot</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>flashcards-springboot</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

form in html

<html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div>
            <form action="processChoice" method="post">
                <input type="radio" name="choicebean" value="1" checked=true>1<br>
                <input type="radio" name="choicebean" value="2">2<br>
                <input type="submit" value="Submit"/>
            </form> 
        </div>
    </body>
</html>

Controller

@Controller
public class FileUploadController {

    private static final Logger slf4jLogger
            = LoggerFactory.getLogger(FileUploadController.class);

    // Holds keys, values in order
    Map<String, String> map = new LinkedHashMap<>();

    @Autowired
    private Utils utils;

    @Autowired
    ChoiceBean choiceBean;

    @GetMapping("/")
    public String home() throws IOException {
        return "home";
    }

    // Called from home view
    @PostMapping("/upload")
    public String handleFileUpload(
            @RequestParam("file") MultipartFile file, Model model) {
        // Clear map in case of new file upload
        map.clear();
        try {
            // Add map to model
            model.addAttribute("theMap",
                    utils.mapInputStringToMap(file.getBytes()));
        } catch (IOException ex) {
            slf4jLogger.error(FileUploadController.class.getName(), ex.getCause());
        }
        return "choice-1";
    }

    // Map object to attribute
    @ModelAttribute("choice")
    public ChoiceBean getChoice(HttpServletRequest request) 
    {
        return (ChoiceBean) request.getAttribute("choicebean");
    }

    @PostMapping("/processChoice")
    public String processChoiceGet(
        @ModelAttribute("choice") ChoiceBean choice, Model model) {

        // Log
        slf4jLogger.info("result: " + choice.getChoice());
        model.addAttribute("choice",choice.getChoice());
        return "flash-card";  
}

Output view

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
    <head>
        <title>Getting Started: Serving Web Content</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body>
        <p th:text="'Hello, ' + ${choice} + '!'" />
    </body>
</html>

EDIT: I added an array of numbers to be used as radio button display in handleFileUpload() [<-this works]; also removed getString() from choice:

@Controller
public class FileUploadController {

    private static final Logger slf4jLogger
            = LoggerFactory.getLogger(FileUploadController.class);

    // Holds keys, values in order
    Map<String, String> map = new LinkedHashMap<>();

    @Autowired
    private Utils utils;
    @Autowired
    ChoiceBean choiceBean;

    @GetMapping("/")
    public String home() throws IOException {
        return "home";
    }

    // Called from home view
    @PostMapping("/upload")
    public String handleFileUpload(
            @RequestParam("file") MultipartFile file, Model model) {
        // Clear map in case of new file upload
        map.clear();
        try {
            // Add map to model
            model.addAttribute("theMap",
                    utils.mapInputStringToMap(file.getBytes()));
            model.addAttribute("sources", new String[]{"1", "2"});

        } catch (IOException ex) {
            slf4jLogger.error(FileUploadController.class.getName(), ex.getCause());
        }
        return "choice-1";
    }

    @ModelAttribute("choice")
    public ChoiceBean getChoice(HttpServletRequest request) 
    {
        return (ChoiceBean) request.getAttribute("choicebean");
    }

    @PostMapping("/processChoice")
    public String processChoiceGet(
        @ModelAttribute("choice") ChoiceBean choice, Model model) {

        // Log
        slf4jLogger.info("result: " + choice);
        model.addAttribute("choice",choice);
        return "flash-card";
    }
}

...and edited the form to try to capture the command object as 'choice', but value is still null in the view. How can I get the chosen radio button value as a string to display in the view?

<form th:object="${choice}" th:action="@{/processChoice}" method="post">
    <div th:each="source : ${sources}">
        <input name="source" type="radio" th:value="${source}"/>
        <label th:for="source" th:text="${source}">my label</label>
    </div>
    <input type="submit" value="Submit"/>
</form> 

2 Answers 2

0

You need to use th:each

<input type="radio" th:each="me : ${choice}" th:value="${me.choice}">
Sign up to request clarification or add additional context in comments.

5 Comments

So, this is in the form, right? What is 'me' here? And where do my values 1 and 2 go?
Hm, do I need to do something like this where in the controller I create a small array of two integers [1, 2], then add that to the model, then return the string name of the form html file?stackoverflow.com/questions/53124981/…
where do you get the content in 'choice'? Database?
Originally that came from my form radio button selection
Using the below link, in the controller I created a small array of two integers [1, 2], then added that to the model, and the radio buttons appear but still working on submit portion. stackoverflow.com/questions/53124981/…
0

Thanks José Bardales for the suggestion. I was able to use that to make the thymeleaf radio button display look correct, but I wasn't able to get the selected value in the view, so my I ended up using a plain html form.

Below is my solution. It works, but I feel like there is a better way in the controller to bind the radio button value to the choicebean object in Spring but not sure.

Bean...

@Component
public class ChoiceBean {
    private String choice;
    // Getter, setter
}

Form...

<form action="processChoice" method="get">
    <input type="radio" name="radiochoice1" value="1" checked=true>1<br>
    <input type="radio" name="radiochoice1" value="2">2<br>
    <input type="submit" value="Submit"/>
</form>

Controller...

public String processChoiceGet(@RequestParam String radiochoice1,
        ChoiceBean choice, Model model) {
    choice.setChoice(radiochoice1);
    model.addAttribute("choice",choice);
    return "flash-card";

View...

<body>
    <p th:text="'choice is ' + ${choice.choice} + '!'" />
</body>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.