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

使用Jsoup调用AddExamType接口时遭遇HTTP 500错误求助

Troubleshooting Jsoup 500 Error When Adding Exam Type

Hey there, let's break down how to fix that 500 server error you're hitting with Jsoup. A 500 status means the server ran into an unexpected issue processing your request—usually due to a mismatch between your Jsoup request and what the server expects. Let's go through the most likely fixes based on your code and stack trace.

1. Update Session Cookies After the Initial GET Request

When you fetch the form page with GET, the server might send new session cookies (like updated CSRF tokens or session IDs) that are required for the subsequent POST. Right now, you're reusing the original Common.sessionCookies instead of updating them with the cookies from the GET response. This mismatch can trigger server errors.

Fix: Add this line right after executing the GET request:

// Update session cookies with any new ones from the form page response
Common.sessionCookies.putAll(addExamResponse.cookies())

2. Fix the utf8 Form Field

Your current code sets utf8 to "e2 9c 93"—this is the byte representation of the checkmark character, but most websites expect the actual character (✓) or the value pulled directly from the form. Using the wrong value can break server-side parsing.

Better Fix: Extract the utf8 value directly from the form page instead of hardcoding it:

val utf8Value = document.select("input[name=utf8]").first()?.attr("value") ?: "✓"

Then use this value in your form data instead of the hardcoded byte string.

3. Use a Realistic User-Agent String

Your current User-Agent is just "Mozilla"—many servers validate for full browser-like User-Agent strings and reject or error on overly simple ones.

Fix: Replace your User-Agent with a full, real-world string:

.userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")

Use this for both the GET and POST requests.

4. Add Comprehensive Exception Handling

Your existing try-catch only catches IOException, but even though HttpStatusException is a subclass, your coroutine context might be causing uncaught exceptions. Expanding your catch blocks will prevent crashes and give better debugging info.

Fix: Add specific catches for HttpStatusException and a general Exception catch-all, plus ensure UI updates run on the main thread:

} catch (e: HttpStatusException) {
    Log.e(TAG, "addExam: Server Error - Code: ${e.statusCode}, URL: ${e.url}", e)
    runOnUiThread {
        progressBar.hide()
        Toast.makeText(this, "Server error: ${e.statusCode}", Toast.LENGTH_LONG).show()
    }
} catch (e: IOException) {
    Log.e(TAG, "addExam: Network Error", e)
    runOnUiThread {
        progressBar.hide()
        Toast.makeText(this, "Network issue: ${e.message}", Toast.LENGTH_LONG).show()
    }
} catch (e: Exception) {
    Log.e(TAG, "addExam: Unexpected Error", e)
    runOnUiThread {
        progressBar.hide()
        Toast.makeText(this, "Something went wrong: ${e.message}", Toast.LENGTH_LONG).show()
    }
}

5. Validate Form Fields Against Browser Traffic

The best way to ensure your form data matches what the server expects is to compare it to a real browser request:

  1. Open your target site in Chrome/Firefox, open DevTools (F12), go to the Network tab
  2. Perform a manual "add exam type" action
  3. Find the POST request to /Exam/AddExamType and check:
    • All form fields (including hidden ones you might be missing)
    • Exact field names (case-sensitive—e.g., is it examTypeName instead of ExamTypeName?)
    • Request headers the browser sends (you can copy these into your Jsoup request if needed)

Modified Code Example

Here's your code with all the above fixes applied:

private fun addExam() {
    Log.d(TAG, "addExam: Starting exam type addition")
    try {
        // Fetch the form page to get tokens and update cookies
        val addExamResponse = Jsoup.connect(getString(R.string.addExamUrl))
            .method(Connection.Method.GET)
            .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            .cookies(Common.sessionCookies)
            .execute()

        // Update session cookies with new ones from the GET response
        Common.sessionCookies.putAll(addExamResponse.cookies())

        val document = addExamResponse.parse()
        Log.d(TAG, "addExam: Retrieved form page - URL: ${addExamResponse.url()}")

        // Extract required tokens from the form
        val authToken = document.select("input[name=__RequestVerificationToken]").first()?.attr("value")
            ?: throw IllegalStateException("Could not find verification token")
        val utf8Value = document.select("input[name=utf8]").first()?.attr("value") ?: "✓"

        Log.d(TAG, "addExam: Verification token retrieved: $authToken")

        // Build form data with valid values
        val formData = HashMap<String, String>().apply {
            put("utf8", utf8Value)
            put("ExamTypeName", examType.text.toString().trim())
            put("Description", examDesc.text.toString().trim())
            put("__RequestVerificationToken", authToken)
        }

        // Submit the POST request
        val examListPage = Jsoup.connect(getString(R.string.addExamUrl))
            .data(formData)
            .method(Connection.Method.POST)
            .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
            .cookies(Common.sessionCookies)
            .followRedirects(true)
            .execute()

        Log.d(TAG, "addExam: POST response URL: ${examListPage.url()}")

        runOnUiThread {
            progressBar.hide()
        }

        // Handle success/redirect
        if (examListPage.url().toString().lowercase(Locale.ROOT).contains("teacher")) {
            startActivity(Intent(this, HomeActivity::class.java))
            finish()
        } else {
            runOnUiThread {
                Toast.makeText(this, "Failed to add exam type. Please check your input.", Toast.LENGTH_LONG).show()
            }
        }

    } catch (e: HttpStatusException) {
        Log.e(TAG, "addExam: Server Error - Code: ${e.statusCode}, URL: ${e.url}", e)
        runOnUiThread {
            progressBar.hide()
            Toast.makeText(this, "Server error: ${e.statusCode}", Toast.LENGTH_LONG).show()
        }
    } catch (e: IOException) {
        Log.e(TAG, "addExam: Network Error", e)
        runOnUiThread {
            progressBar.hide()
            Toast.makeText(this, "Network issue: ${e.message}", Toast.LENGTH_LONG).show()
        }
    } catch (e: Exception) {
        Log.e(TAG, "addExam: Unexpected Error", e)
        runOnUiThread {
            progressBar.hide()
            Toast.makeText(this, "Something went wrong: ${e.message}", Toast.LENGTH_LONG).show()
        }
    }
}

Give these changes a try—most likely the cookie update or utf8 field fix will resolve the 500 error. If not, comparing your request to the browser's DevTools traffic will help spot any remaining mismatches.

内容的提问来源于stack exchange,提问作者hagar Mohamad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:07:36