使用 REST 模板和 JSON 响应格式在 Spring MVC 上返回 Http Status 500

Posted

技术标签:

【中文标题】使用 REST 模板和 JSON 响应格式在 Spring MVC 上返回 Http Status 500【英文标题】:Http Status 500 returned on Spring MVC Using REST Templates and JSON Response Format 【发布时间】:2014-12-23 18:46:23 【问题描述】:

我的项目由以下四个表组成:

    问题 - Question_id,问题文本 用户 - 用户 ID、姓名 Question_Answer - 用户 ID、Question_ID、答案 QuestionType - QuestionID、标签

我必须根据多个标签生成问题

或者简单地返回所有问题的列表(当没有提供标签时)

或者将用户提供的答案插入到Question_Answer表中。

Controller类SpringServiceController.java(生成JSON格式的结果)如下:

package com.bargadss.SpringService.Controller;

import java.text.ParseException;
import java.util.List;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.bargadss.SpringService.DAO.QuestionService;
import com.bargadss.SpringService.Domain.*;


@RestController

@RequestMapping("/service/question/")
public class SpringServiceController 
  QuestionService questionService=new QuestionService();

 @RequestMapping(value = "/tag1,tag2,tag3", method =  RequestMethod.GET,headers="Accept=application/json")
 public List<Questions> getQuestions(@PathVariable("tag1") String tag1, @PathVariable("tag2") String tag2, @PathVariable("tag3") String tag3) 
  List<Questions> Qobj=questionService.getQuestionByTag(tag1, tag2, tag3);
  return Qobj;
 

 @RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
 public List<Questions> getAllQuestions()   
  List<Questions> Qobj=questionService.getAllQuestion();
  return Qobj;   
 

 @RequestMapping(value="/insert/user_id/question_id/answer",method = RequestMethod.POST,headers="Accept=application/json")
  public List<Questions> addQuestions(@PathVariable int user_id,@PathVariable int question_id,@PathVariable String answer) throws ParseException  
      Question_Answer qtnAns = new Question_Answer();
      qtnAns.setUser_id(user_id);
      qtnAns.setQuestion_id(question_id);
      qtnAns.setAnswer(answer);
      questionService.insertAnswer(qtnAns.getUser_id(), qtnAns.getQuestion_id(), qtnAns.getAnswer());
      return questionService.getAllQuestion();        
          
  

ListQuestionController.java使用Spring REST模板(生成JSP页面)如下:

package com.bargadss.SpringService.Controller;

import java.util.LinkedHashMap;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import com.bargadss.SpringService.Domain.*;

@Controller
public class ListQuestionController 

 @RequestMapping("/listQuestion/tag1,tag2,tag3")
    public ModelAndView listQuestions(@PathVariable("tag1") String Tag1, @PathVariable("tag2") String Tag2, @PathVariable("tag3") String Tag3)  
        RestTemplate restTemplate = new RestTemplate();
        String url="http://localhost:8080/FetchQuestions/service/question/tag1,tag2,tag3";
        List<LinkedHashMap> Qobj=restTemplate.getForObject(url, List.class,Tag1,Tag2,Tag3);
        return new ModelAndView("listQuestion", "questions", Qobj);
    

 @RequestMapping("/listAllQuestion/")
    public ModelAndView listAllQuestion()  
        RestTemplate restTemplate = new RestTemplate();
        String url="http://localhost:8080/FetchQuestions/service/question/";
        List<LinkedHashMap> Qobj=restTemplate.getForObject(url, List.class);
        return new ModelAndView("listQuestion", "questions", Qobj);
    

 @RequestMapping("/insertQuestionAnswer/user_id/qtn_id/answer")
    public ModelAndView insertQuestionAnswer(@PathVariable("user_id") String user_ID,
           @PathVariable("qtn_id") String qtn_ID, @PathVariable("answer") String answer)  
        RestTemplate restTemplate = new RestTemplate();
        String url="http://localhost:8080/FetchQuestions/service/question/insert/user_id/qtn_id/answer";
        List<LinkedHashMap> Qobj=restTemplate.getForObject(url, List.class,user_ID,qtn_ID,answer);
        return new ModelAndView("listQuestion", "questions", Qobj);
    

  

QuestionService.java 类执行 DAO 活动如下:

package com.bargadss.SpringService.DAO;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import com.bargadss.SpringService.Domain.*;
import com.bargadss.SpringService.Utility.DBUtility;


public class QuestionService 

private Connection connection;

 public QuestionService() 
  connection = DBUtility.getConnection();
 

 public void insertAnswer(int userId,int qtnId,String answer)
    //Question_Answer objQA = new Question_Answer();
    PreparedStatement preparedStatement = null;
    try
         preparedStatement = connection.prepareStatement("insert into question_answer values (?,?,?)");
         preparedStatement.setInt(1, userId);
         preparedStatement.setInt(2, qtnId);
         preparedStatement.setString(3, answer);
         int result = preparedStatement.executeUpdate();
         if(result == 0)
            System.out.println("INSERTION OF DATA FAILED");
     catch (SQLException e)
         e.printStackTrace();
    
    finally
        try  if (preparedStatement != null) preparedStatement.close();  catch (Exception e) System.out.println("Exception Closing The Prepared Statement");e.printStackTrace();;
    
 

 public List<Questions> getAllQuestion()
     Questions objQ = new Questions();
     ResultSet rs = null;
     PreparedStatement preparedStatement = null;
     List<Questions> qtns = new ArrayList<Questions>();
     try 
           preparedStatement = connection.prepareStatement("select * from questions");             
           rs = preparedStatement.executeQuery();

           while(rs.next()) 
            objQ.setQuestion_id(Integer.parseInt( rs.getString("Question_id") ) );
            objQ.setQuestion_text(rs.getString("Question_Text"));
            qtns.add(objQ);   
           
      catch (SQLException e) 
           e.printStackTrace();
           
       finally
           try  if (rs != null) rs.close();  catch (Exception e) System.out.println("Exception Closing The result Set");e.printStackTrace();;
           try  if (preparedStatement != null) preparedStatement.close();  catch (Exception e) System.out.println("Exception Closing The Prepared Statement");e.printStackTrace();;
           /*try  if (connection != null) connection.close();  catch (Exception e) System.out.println("Exception Closing The Connection");e.printStackTrace();;*/
       
    return qtns;
 

 public List<Questions> getQuestionByTag(String Tag1,String Tag2,String Tag3)       
     Questions objQ = new Questions();
     ResultSet rs = null;
     PreparedStatement preparedStatement = null;
     List<Questions> qtns = new ArrayList<Questions>();
     try 
           preparedStatement = connection.
           prepareStatement("select questions.Question_id,questions.Question_Text from questions,questiontype " +
                            "where questions.Question_id=questiontype.Question_id " +
                            "and questiontype.Tag in (?,?,?)");
           preparedStatement.setString(1, Tag1);
           preparedStatement.setString(2, Tag2);
           preparedStatement.setString(3, Tag3);
           rs = preparedStatement.executeQuery();

           while(rs.next()) 
            objQ.setQuestion_id(Integer.parseInt( rs.getString("Question_id") ) );
            objQ.setQuestion_text(rs.getString("Question_Text"));
            qtns.add(objQ);   
           
      catch (SQLException e) 
           e.printStackTrace();
           
       finally
           try  if (rs != null) rs.close();  catch (Exception e) System.out.println("Exception Closing The result Set");e.printStackTrace();;
           try  if (preparedStatement != null) preparedStatement.close();  catch (Exception e) System.out.println("Exception Closing The Prepared Statement");e.printStackTrace();;
           /*try  if (connection != null) connection.close();  catch (Exception e) System.out.println("Exception Closing The Connection");e.printStackTrace();;*/
       
    return qtns;



在执行项目时(Apache Tomcat 7.0.12) 使用以下 URL 会生成 HTTP STATUS 500

http://localhost:8080/FetchQuestions/insertQuestionAnswer/3/9/True

此外,当我执行以下 URL 时,它会生成 HTTP 状态 405 - 不支持请求方法“GET”

http://localhost:8080/FetchQuestions/service/question/insert/3/9/True

我做错了什么?我错过了什么吗?

HTTP 状态 500 的堆栈跟踪如下:

严重:servlet [rest] 的 Servlet.service() 在路径 [/FetchQuestions] 的上下文中抛出异常 [请求处理失败;嵌套异常是 org.springframework.web.client.HttpClientErrorException: 405 Method Not Allowed] 根本原因 org.springframework.web.client.HttpClientErrorException:405 方法不允许 在 org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91) 在 org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:576) 在 org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:532) 在 org.springframework.web.client.RestTemplate.execute(RestTemplate.java:489) 在 org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:226) 在 com.bargadss.SpringService.Controller.ListQuestionController.insertQuestionAnswer(ListQuestionController.java:47) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:214) 在 org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:748) 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 在 org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 在 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 在 java.lang.Thread.run(Thread.java:745)

【问题讨论】:

你是用断点调试的吗? 是的,我调试了代码并对其进行了测试。 能否请您添加堆栈跟踪 请分享异常堆栈跟踪 Http 状态 405 返回以下堆栈跟踪 - >2014 年 10 月 28 日下午 5:23:47 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleHttpRequestMethodNotSupported 警告:不支持请求方法“GET” 【参考方案1】:

当我执行以下 URL 时,它还会生成 HTTP 状态 405 - 不支持请求方法“GET”

SpringServiceController.SpringServiceController方法的请求方法从POST改为GET。它应该可以解决您的问题。

@RequestMapping(value="/insert/user_id/question_id/answer",method = RequestMethod.GET,headers="Accept=application/json")

【讨论】:

以上是关于使用 REST 模板和 JSON 响应格式在 Spring MVC 上返回 Http Status 500的主要内容,如果未能解决你的问题,请参考以下文章

用于 Android 客户端的 Django Rest Framework 响应的通用 JSON 格式

在动态信封中包装 json 响应 - Rest api

如何使用Spring Boot REST生成自定义JSON响应?

模板中的 Django Json 响应格式

PayPal REST API 格式错误的 JSON 错误

在PowerShell中序列化REST响应