Android 应用程序上的发布请求(提交答案)中出现 500 内部服务器错误

问题描述 投票:0回答:1

这将是一篇很长的文章,因为它涵盖了我的应用程序的后端和前端,我将详细介绍 Laravel、Postman Json 返回和 Kotlin Jetpack Compose 中的每个代码。我正在创建一个问卷应用程序,用户可以通过单选按钮选择输入答案,然后提交答案。

基本上,用户填写每个单选按钮,它将存储在本地主机 phpMyAdmin 数据库中

我尝试调试几个小时的一个问题是我似乎无法提交答案,并且在 Android Studio Logcat 中,此代码片段中显示 500 Internal Server Error:

AnswerModel(answers=[Answer(question_id=1, answer=3)], user_id=1, fill_date=22-6-24)
Failed to submit answers: HTTP 500 Internal Server Error

基本上,php laravel 代码中有一个答案和提交控制器,它与答案和结果数据库相关,用于存储输入的答案。这是提交控制器:


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Answer;
use App\Models\Result;

class SubmitController extends Controller
{
    public function store(Request $request){

        $request_answer = json_decode($request->input('answers'), true);

        $totalScore = 0;
        foreach ($request_answer as $key => $value) {
             Answer::create([
                'user_id' => $request->input('user_id'),
                'question_id' => $value['question_id'],
                'answer_value' => $value['answer'],
                'created_at' => now(),
                'updated_at' => now(),
            ]);
            $totalScore += $value['answer'];

        }
        $result = Result::create([
            'user_id' => $request->input('user_id'),
            'fill_date'=> $request->input('fill_date'),
            'score'=> $totalScore,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
        return response()->json(['message' => 'Answers submitted successfully', 'result' => ""]);
    }
}

接下来是提交api的表单数据。我已经测试过它并且有效。

答案:

[
  {
    "question_id" : "1",
    "answer" : "3",
    "user_id": "1"
  },
   {
    "question_id" : "2",
    "answer" : "3",
    "user_id": "1"
  },
   {
    "question_id" : "3",
    "answer" : "3",
    "user_id": "1"
  }
]

用户 ID:

1

填写日期:

24-7-24

接下来是android代码。有一些与此过程相关的代码片段,包括数据类、存储库、视图模型和视图屏幕。

以下是数据类:

data class AnswerModel(
    val answers: List<Answer>,
    val user_id: String,
    val fill_date: String
)

下一个数据类:

data class Answer(
    val question_id: String,
    val answer: String
)

最终响应数据类:

data class AnswerResponse(
    val message: String,
    val result: Result
)

接下来,这是用于此 POST api 的 api 代码:



@Singleton
interface EMedibApi {

//api and post data
    @POST("submit")
    suspend fun submitAnswers(@HeaderMap headers: Map<String , String>,
                              @Body request: AnswerModel): AnswerResponse
}

之后,这是视图模型(我在这里使用了submitAnswers函数):

@HiltViewModel
class DsmqViewModel @Inject constructor(private val repository: DsmqRepository) : ViewModel() {
      var isLoading: Boolean by mutableStateOf(false)
      var questions: QuestionResponse? by mutableStateOf(
          QuestionResponse(
              data = null
          )
      )
    init {
        fetchQuestions()
//        fetchResults()
    }


    private fun fetchQuestions() {
        viewModelScope.launch {
            isLoading = true
            try {
                when (val response = repository.getQuestions()) {
                    is Resource.Success -> {
                        Log.d("DSMQ DATA", "${response.data}")
                        questions = response.data!!
                    }
                    is Resource.Error -> {
                        Log.d("DSMQ DATA", "${response.message}")
                    }
                    else -> {
                        Log.d("DSMQ DATA", "$response")
                    }
                }
            } catch (e: HttpException) {
                Log.e("DsmqViewModel", "Failed to fetch questions: ${e.message}")
            } finally {
                isLoading  = false
            }
        }
    }
    fun submitAnswers(answers: List<Answer>, headers: Map<String, String> , userId: String, fillDate: String) {
        viewModelScope.launch {
            isLoading = true
            val answerModel = AnswerModel(
                answers = answers,
                user_id = userId,
                fill_date = fillDate
            )
            Log.d("DSMQ SUBMIT", answerModel.toString())
            try {
                when (val response = repository.submitAnswers(answerModel, headers)) {
                    is Resource.Success -> {
                        Log.d("DSMQ SUBMIT", "Answers submitted successfully: ${response.data}")
                    }
                    is Resource.Error -> {
                        Log.d("DSMQ SUBMIT", "Failed to submit answers: ${response.message}")
                    }
                    else -> {
                        Log.d("DSMQ SUBMIT", "Unknown response: $response")
                    }
                }
            } catch (e: HttpException) {
                Log.e("DsmqViewModel", "Failed to submit answers: ${e.response()}")
            } finally {
                isLoading = false
            }
        }
    }
}

接下来是存储库

//the dsmq repository
class DsmqRepository @Inject constructor(private val api: EMedibApi) {


    suspend fun getQuestions(): Resource<QuestionResponse>{
        Resource.Loading(data = true)
        return try {
            val dataQuestion = api.getQuestions()
            Resource.Success(data =  dataQuestion)
        } catch (e: Exception) {
            Resource.Error(message = e.message.toString())
        } finally {
            Resource.Loading(data = false)
        }
    }

    //create function for submittingAnswers
    suspend fun submitAnswers(answerModel: AnswerModel, headers: Map<String, String>): Resource<AnswerResponse> {
        Resource.Loading(data = true)
        return try {
            val responseSubmit = api.submitAnswers(headers, answerModel)
            Resource.Success(data = responseSubmit)
        } catch (e: Exception) {
            Resource.Error(message = e.message.toString())
        } finally {
            Resource.Loading(data = false)
        }
    }
    
}

最后,这是与提交答案相关的视图/屏幕/功能。 QuestionItem.kt代码:

@Composable
fun QuestionItem(
    question: String,
    options: List<Option>,
    onAnswerSelected: (Answer) -> Unit
) {
    var selectedOptionId by remember { mutableStateOf(-1) }

    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = question,
            textAlign = TextAlign.Center,
            style = MaterialTheme.typography.bodyMedium,
            modifier = Modifier
                .fillMaxWidth()
                .padding(bottom = 8.dp)
        )

        val optionTexts = options.map { it.option_text ?: "No options provided" }
        val textAboveOptions = listOf(
            "Sangat berlaku bagi saya",
            "Berlaku bagi saya",
            "Sedikit berlaku bagi saya",
            "Tidak berlaku bagi saya"
        )
        HorizontalRadioButton(
            options = optionTexts,
            textAboveOptions = textAboveOptions,
            selectedOption = selectedOptionId,
            onOptionSelected = { optionId ->
                selectedOptionId = optionId
                if (options.isNotEmpty()) {
                    val selectedOption = options.find { it.id == optionId }
                        selectedOption?.let {
                             val answer = Answer(
                                question_id = it.question_id.toString(),
                                 answer = it.option_text
                             )
                    onAnswerSelected(answer)
                     }
                }
            }
        )
    }
}

最后全屏(在startQuestionnaire if语句之后使用Answer数据类):

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DsmqScreen(
    navController: NavController,
    viewModel: DsmqViewModel = hiltViewModel(),
) {
    val customSelectedColor = Color(0xFF5799FC)
    val lightGreen = Color(0xFF13ECA2)
    val redColor = Color(0xFFF20D3F)

    //val selectedAnswers = remember { mutableStateListOf<AnswerResponse>() }
    val selectedAnswers = remember { mutableStateListOf<Answer>() }
    var showDialog by remember { mutableStateOf(false) }
    var showSubmitDialog by remember { mutableStateOf(false) }
    var startQuestionnaire by remember { mutableStateOf(false) }
    var selectedDate by remember { mutableStateOf("") }
    var showInfoDialog by remember { mutableStateOf(false) }

    Scaffold(
        topBar = {
            CenterAlignedTopAppBar(
                title = {
                    Text(
                        text = "Diabetes Self-Management Questionnaire",
                        style = MaterialTheme.typography.bodyMedium,
                        textAlign = TextAlign.Center,
                        fontWeight = FontWeight.SemiBold,
                        color = Color.White
                    )
                },
                colors = TopAppBarDefaults.centerAlignedTopAppBarColors(containerColor = customSelectedColor)
            )
        }
    ) {
        it
        Column(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxHeight()
                .verticalScroll(rememberScrollState())
        ) {
            Spacer(modifier = Modifier.height(62.dp))
            Button(
                onClick = { showInfoDialog = true },
                modifier = Modifier.align(Alignment.CenterHorizontally),
                colors = ButtonDefaults.buttonColors(customSelectedColor)
            ) {
                Text(text = "Apa itu Diabetes Self Management Questionnaire?", color = Color.White)
            }

            if (showInfoDialog) {
                InfoAlertDialog(
                    onDismiss = { showInfoDialog = false }
                )
            }

            EnterDate(selectedDate = selectedDate, onDateSelected = { selectedDate = it })
            Spacer(modifier = Modifier.height(2.dp))


            Button(
                    onClick = {
                        if (selectedDate.isNotEmpty()) {
                            showDialog = true
                        }
                    },
                    modifier = Modifier.align(Alignment.CenterHorizontally),
                    colors = ButtonDefaults.buttonColors(customSelectedColor)
                ) {
                    Text(text = "Mulai Isi Kuesioner")
                }
            Spacer(modifier = Modifier.height(20.dp))
            StartQuestionnaireDialog(
                showDialog = showDialog,
                onDismiss = {
                    showDialog = false
                },
                onConfirm = {
                    showDialog = false
                    startQuestionnaire = true
                },
                confirmButtonColor = lightGreen,
                dismissButtonColor = redColor
            )

            if (startQuestionnaire) {
                Column {
                    viewModel.questions?.data?.forEach { it ->
                        QuestionItem(
                            question = it.question_text,
                            options = it.options ?: emptyList(),
                            onAnswerSelected = { answer ->
                                Log.d("DSMQ", "Answer Selected: $answer")
                                selectedAnswers.removeIf { it.question_id == answer.question_id }
                                selectedAnswers.add(answer)
                            }
                        )
                    }
                    //Spacer(modifier = Modifier.height(16.dp))
                    Button(
                        onClick = { showSubmitDialog = true },
                        modifier = Modifier.align(Alignment.CenterHorizontally),
                        colors = ButtonDefaults.buttonColors(customSelectedColor)
                    ) {
                        Text(text = "Selesai Kuesioner", color = Color.White)
                    }
                    Spacer(modifier = Modifier.height(76.dp))
                }
            }
            if (showSubmitDialog) {
                    AlertDialog(
                        onDismissRequest = { showSubmitDialog = false },
                        title = { Text(text = "Submit Answers") },
                        text = { Text(text = "Are you sure you want to submit your answers?") },
                        confirmButton = {
                            Button(
                                onClick = {
                                    val headerMap = mutableMapOf<String, String>()
                                    headerMap["Accept"] = "application/json"
                                    showSubmitDialog = false
                                    val userId = "1"
                                    Log.d("selected Answer", selectedAnswers.toString())
                                    viewModel.submitAnswers(
                                        answers = selectedAnswers.toList(),
                                        userId = userId,
                                        fillDate = selectedDate,
                                        headers = headerMap)
                                        // Handle successful submission, e.g., navigate to result screen
                                        // navController.popBackStack()
                                },
                                colors = ButtonDefaults.buttonColors(containerColor = lightGreen)
                            ) {
                                Text(text = "Yes", color = Color.White)
                            }
                        },
                        dismissButton = {
                            Button(
                                onClick = { showSubmitDialog = false },
                                colors = ButtonDefaults.buttonColors(containerColor = redColor)
                            ) {
                                Text(text = "No", color = Color.White)
                            }
                        }
                    )
                }
            //customprofile list tile to questionnaire
            CustomTile(
                title = "Hasil DSMQ",
                subtitle ="Pantau Hasil DSMQ Anda" ,
                leadingIcon = Icons.Outlined.Calculate,
                onClick = {
                    //navigasi
                }
            )
            Spacer(modifier = Modifier.height(96.dp))
        }
    }
}

我一直渴望得到答案,但我不知道为什么它不断给出 500 内部服务器错误。我已经完成了:

php artisan serve

激活本地主机服务器,但它一直给我错误代码 500。我已经测试了所有其他 API,它们似乎可以工作。

laravel android-jetpack-compose postman mobile-development
1个回答
0
投票

更新:我已经修复了它,并且邮递员和 Android API 测试都有效。

显然我只需要更新 laravel 上的 Submitcontroller :


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Answer;
use App\Models\Result;

class SubmitController extends Controller
{
    public function store(Request $request){

        $request_answer = is_string($request->input('answers')) ? json_decode($request->input('answers'), true) : $request->input('answers');
        //$request_answer = json_decode($request->input('answers'), true);

        if (is_null($request_answer) || !is_array($request_answer)) {
            return response()->json(['message' => 'Invalid answers data'], 400);
        }
        $totalScore = 0;
        foreach ($request_answer as $key => $value) {
             Answer::create([
                'user_id' => $request->input('user_id'),
                'question_id' => $value['question_id'],
                'answer_value' => $value['answer'],
                'created_at' => now(),
                'updated_at' => now(),
            ]);
            $totalScore += $value['answer'];
        }
        $result = Result::create([
            'user_id' => $request->input('user_id'),
            'fill_date'=> $request->input('fill_date'),
            'score'=> $totalScore,
            'created_at' => now(),
            'updated_at' => now(),
        ]);
        return response()->json(['message' => 'Answers submitted successfully', 'result' => $result]);
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.