You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Thymeleaf邮件表单无刷新提交问题咨询

Hey there! Let's fix that page refresh issue when submitting your email form in Spring Boot with Thymeleaf. The key here is to use AJAX for asynchronous form submission—this way the page stays intact while the controller does its work, and you won't need to pass service objects to the view at all. Here's a step-by-step solution:

1. Adjust Your Thymeleaf Form

First, tweak your start_page.html form to remove default submission behavior and add identifiers for JavaScript targeting. Keep using Thymeleaf's field binding as you already are—no need to change that:

<form id="emailForm" th:object="${emailRequest}">
    <div class="form-group">
        <label for="to">收件人邮箱</label>
        <input type="email" id="to" th:field="*{to}" class="form-control" required>
    </div>
    <div class="form-group">
        <label for="subject">邮件主题</label>
        <input type="text" id="subject" th:field="*{subject}" class="form-control" required>
    </div>
    <div class="form-group">
        <label for="content">邮件内容</label>
        <textarea id="content" th:field="*{content}" class="form-control" rows="5" required></textarea>
    </div>
    <button type="submit" id="submitBtn" class="btn btn-primary">发送邮件</button>
    <!-- 用于显示提交结果的提示区域 -->
    <div id="submitResult" class="mt-3"></div>
</form>
2. Add AJAX Submission Logic

Use vanilla JavaScript (or jQuery if you prefer) to intercept the form submission, send data asynchronously, and handle the controller's response without reloading the page.

Vanilla JS Version:

document.getElementById('emailForm').addEventListener('submit', function(e) {
    // 阻止表单默认提交行为(关键!)
    e.preventDefault();

    // 收集表单数据
    const formData = new FormData(this);

    // 发送AJAX请求
    fetch('/send-email', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        const resultDiv = document.getElementById('submitResult');
        if (data.success) {
            resultDiv.textContent = '邮件发送成功!';
            resultDiv.className = 'mt-3 text-success';
            // 重置表单
            this.reset();
        } else {
            resultDiv.textContent = `发送失败:${data.errorMsg}`;
            resultDiv.className = 'mt-3 text-danger';
        }
    })
    .catch(error => {
        const resultDiv = document.getElementById('submitResult');
        resultDiv.textContent = `请求出错:${error.message}`;
        resultDiv.className = 'mt-3 text-danger';
    });
});

jQuery Version (if you already use it):

$('#emailForm').submit(function(e) {
    e.preventDefault();
    
    $.ajax({
        url: '/send-email',
        type: 'POST',
        data: $(this).serialize(),
        success: function(data) {
            const $result = $('#submitResult');
            if (data.success) {
                $result.text('邮件发送成功!').removeClass('text-danger').addClass('text-success');
                $('#emailForm')[0].reset();
            } else {
                $result.text(`发送失败:${data.errorMsg}`).removeClass('text-success').addClass('text-danger');
            }
        },
        error: function(xhr, status, error) {
            $('#submitResult').text(`请求出错:${error}`).addClass('text-danger');
        }
    });
});
3. Update Your Controller to Return JSON

Modify your existing controller method to return a JSON response instead of a view. This way, the AJAX call can parse the result easily:

First, create simple DTOs for request and response:

// 邮件请求DTO(和你之前绑定的对象一致即可)
public class EmailRequest {
    private String to;
    private String subject;
    private String content;

    // Getters and Setters
}

// 邮件响应DTO
public class EmailResponse {
    private boolean success;
    private String errorMsg;

    // 构造方法
    public EmailResponse(boolean success) {
        this.success = success;
    }

    public EmailResponse(boolean success, String errorMsg) {
        this.success = success;
        this.errorMsg = errorMsg;
    }

    // Getters and Setters
}

Then, adjust the controller method:

@PostMapping("/send-email")
@ResponseBody // 告诉Spring返回JSON而非视图
public ResponseEntity<EmailResponse> sendEmail(@ModelAttribute EmailRequest emailRequest) {
    try {
        // 调用你的邮件发送服务逻辑
        emailService.sendEmail(emailRequest.getTo(), emailRequest.getSubject(), emailRequest.getContent());
        return ResponseEntity.ok(new EmailResponse(true));
    } catch (Exception e) {
        // 捕获异常并返回失败信息
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(new EmailResponse(false, e.getMessage()));
    }
}
4. Key Notes to Keep in Mind
  • CSRF Protection: Spring Boot enables CSRF by default, but Thymeleaf automatically adds a hidden CSRF token to your form. Using FormData or serialize() will include this token in the request, so no extra work needed.
  • Mail Service Configuration: Ensure your application.properties has correct mail server settings (example below):
    spring.mail.host=smtp.your-mail-provider.com
    spring.mail.port=587
    spring.mail.username=your-email@example.com
    spring.mail.password=your-app-password
    spring.mail.properties.mail.smtp.auth=true
    spring.mail.properties.mail.smtp.starttls.enable=true
    

This approach keeps your page static during submission, avoids passing service objects to the view, and gives you full control over user feedback!

内容的提问来源于stack exchange,提问作者Mohammed Housseyn Taleb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:01:13