Java Web Service调用异常:Menu服务无法调用但其他服务正常
Hey there, since your /hello endpoint works perfectly, your core Jersey and Tomcat setup is solid. Let's break down the likely issues with your /menu service and fix them one by one:
1. Uninitialized Database Connection (conn)
Your Connection conn; is declared but never assigned a valid value. When you call conn.createStatement(), this will throw a NullPointerException immediately—this is almost certainly the root cause of your endpoint failing.
You mentioned a DBManager in your Hello service (commented out), so reuse that same pattern to get a working connection. For example:
// Replace the raw Connection declaration with this Connection conn = DBManager.getInstance().getConnection(); // Adjust based on your DBManager's actual method name
Always ensure you're working with a properly opened connection before executing database queries.
2. Mismatched Constructor & Query Columns
There are critical mismatches between your SQL query and the Menu constructor call that will trigger SQLException:
- Your query selects
id_produs, nume_produs, pret, imagine, descriere, but your constructor tries to fetchid_chelner(a column not included in the query) and treatsdescriereas an integer (it’s almost certainly a string field in your database).
Fix the constructor call to match your selected columns exactly:
Menu rp = new Menu( rs.getInt("id_produs"), rs.getString("nume_produs"), rs.getFloat("pret"), // Confirm your "pret" column type matches (use getDouble if needed) rs.getString("imagine"), // Add the "imagine" field you selected but weren't using rs.getString("descriere") // "descriere" should be a string, not an int );
Double-check that your Menu class has a constructor that accepts these exact parameter types.
3. Missing Serialization Requirements for the Menu Class
Jackson (the JSON provider you’re using) needs your Menu class to meet basic serialization rules to convert the list to JSON:
- A no-argument constructor (required for Jackson to instantiate objects)
- Public getter methods for all fields you want included in the JSON response
Without these, Jersey will throw a serialization error, resulting in a 500 Internal Server Error. Here’s a valid example of the Menu class:
public class Menu { private int idProdus; private String numeProdus; private float pret; private String imagine; private String descriere; // Required no-arg constructor public Menu() {} // Parameterized constructor matching your query public Menu(int idProdus, String numeProdus, float pret, String imagine, String descriere) { this.idProdus = idProdus; this.numeProdus = numeProdus; this.pret = pret; this.imagine = imagine; this.descriere = descriere; } // Getters for all fields (required for JSON serialization) public int getIdProdus() { return idProdus; } public String getNumeProdus() { return numeProdus; } public float getPret() { return pret; } public String getImagine() { return imagine; } public String getDescriere() { return descriere; } }
4. Improved Exception Handling
Right now, you’re only printing the stack trace and returning null when an exception occurs. This makes debugging hard because you won’t see error details in the client response. Instead, use JAX-RS’s Response object to return a meaningful error status:
@GET @Produces(MediaType.APPLICATION_JSON) public Response getMenu() { try (Statement st = conn.createStatement()) { List<Menu> menu = new ArrayList<>(); String query = "SELECT id_produs, nume_produs, pret, imagine, descriere FROM meniu;"; // Use try-with-resources for ResultSet to auto-close it try (ResultSet rs = st.executeQuery(query)) { while (rs.next()) { Menu rp = new Menu( rs.getInt("id_produs"), rs.getString("nume_produs"), rs.getFloat("pret"), rs.getString("imagine"), rs.getString("descriere") ); menu.add(rp); } } return Response.ok(menu).build(); } catch (SQLException e) { e.printStackTrace(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Failed to fetch menu: " + e.getMessage()) .build(); } }
5. Double-Check Resource Registration
Even though other endpoints work, confirm that MenuWebService is being registered by Jersey:
- If you’re using a custom
Applicationclass, ensure you’ve addedMenuWebService.classto the set of classes returned bygetClasses() - If you’re using package scanning in
web.xml, verifyMenuWebServiceis in a package that’s being scanned (look for the<param-value>underjersey.config.server.provider.packages)
After fixing these issues, restart your Tomcat server and test the /menu endpoint again. You’ll either see your menu data as JSON or a clear error message to help debug any remaining issues.
内容的提问来源于stack exchange,提问作者John

