如何为Spring指定接口设置HTTP响应码与HTTP方法?附代码
Hey there! Let's refine your Spring /graph POST endpoint to properly handle HTTP status codes and follow best practices for HTTP method configuration. Here's a step-by-step solution:
1. Simplify HTTP Method Declaration
Instead of using the verbose @RequestMapping(method = RequestMethod.POST), Spring 4.3+ offers @PostMapping as a concise, intent-driven alternative. It makes your code cleaner and immediately signals this endpoint only accepts POST requests.
2. Use ResponseEntity for Flexible Response Control
Returning HttpServletResponse works, but ResponseEntity is the Spring MVC recommended approach—it lets you easily pair response bodies with appropriate HTTP status codes without manually manipulating the response object.
3. Map Scenarios to Correct HTTP Status Codes
Let's align each execution path with standard HTTP status codes:
- Success (graph saved successfully): Return
201 Created(since you're creating a new resource in the database) or200 OKif you prefer. - File Not Found: Return
404 Not Foundto indicate the requestedgraph.jsondoesn't exist. - General Exceptions: Return
500 Internal Server Errorfor unexpected issues like JSON parsing failures or database errors.
4. Full Revised Code Example
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.json.JSONObject; import org.json.JSONParser; import java.io.FileReader; import java.io.FileNotFoundException; @RestController // Combines @Controller and @ResponseBody, so you can omit @ResponseBody on methods public class GraphController { // Assume your Hibernate Session is injected or obtained properly private final Session session; public GraphController(Session session) { this.session = session; } @PostMapping("/graph") // Replaces @RequestMapping with method=POST public ResponseEntity<GraphJson> graphImport() { JSONParser parser = new JSONParser(); try { Object obj = parser.parse(new FileReader("graph.json")); JSONObject jsonObject = (JSONObject) obj; GraphJson graph = new GraphJson(); graph.setSource(jsonObject.toString()); session.save(graph); // Fetch the saved entity (note: using ID=1 might not be reliable if multiple entries exist) GraphJson savedGraph = session.get(GraphJson.class, 1); // Return 201 Created with the saved graph as response body return new ResponseEntity<>(savedGraph, HttpStatus.CREATED); } catch (FileNotFoundException e) { // Log the error for debugging e.printStackTrace(); // Return 404 Not Found with a message (or empty body if preferred) return new ResponseEntity<>(HttpStatus.NOT_FOUND); } catch (Exception e) { // Catch-all for other errors (JSON parsing, DB issues, etc.) e.printStackTrace(); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } }
Key Notes:
- @RestController: Eliminates the need for
@ResponseBodyon individual methods, as it applies the annotation globally to all handler methods. - Session Injection: I've used constructor injection for the Hibernate
Session(or you could useSessionFactoryto get a session per request) to follow Spring's dependency injection best practices. - ID=1 Warning: Fetching the saved graph with ID=1 might not work if multiple
GraphJsonentries exist. A better approach is to use the return value ofsession.save()(which gives the generated ID) to fetch the saved entity, or just return the graph object you saved directly (sincesession.save()persists it).
内容的提问来源于stack exchange,提问作者Alexandre Bento

