我正在JBOSS EAP 6.2中开发和部署RESTful服务。对于此任务,我使用CXF,Spring和Embedded Derby进行数据存储。 我花了几个小时尝试调试此错误但无法实现。我已经多次检查过数据库是完全空的并且没有任何表。但我总是收到相同的堆栈跟踪。 我也读过类似的问题,但这也没有帮助。 所以,这是代码:
资源类
package eu.pedu.adv16s._4_1800.macv03_macura.logika;
import eu.pedu.adv16s_fw.game_txt.IBag;
import eu.pedu.adv16s_fw.game_txt.IItem;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
/**
* Třída Inventar - představuje inventář pro sbírané věci.
* Kapacita je omezena na dvě věci.
*
* @author Viktor Mačura
* @version semestrální práce 4IT101 ZS 2015/2016
*/
public class Inventar implements IBag
{
private Map<String, Vec> seznamVeci;
static final int kapacita = 2;
/**
* Vytvoření inventáře, věci se ukládají do seznamu
* pomocí HashMap
*/
public Inventar()
{
seznamVeci = new HashMap<>();
/**
* Vkládá věci do inventáře.
* @param Vec vkládáná věc
* @return boolean true pokud je v inventáři místo,
* false pokud v něm není místo
*/
public boolean vlozVec(Vec vec)
{
if (seznamVeci.size() < kapacita)
{
seznamVeci.put(vec.getNazev(), vec);
return true;
}
return false;
}
/**
* Odebírá věc z inventáře.
* @param String název věci
* @return Vec pokud je věc v inventáři, odebere ji a vrátí na ni odkaz,
* pokud neni, vrátí null
*/
public Vec seberVec(String nazev)
{
Vec odebirana = null;
if (seznamVeci.containsKey(nazev))
{
odebirana = seznamVeci.get(nazev);
seznamVeci.remove(nazev);
}
return odebirana;
}
/**
* Zjišťuje, jestli je požadovaná věc v inventáři.
* @param String název věci
* @return boolean true pokud je v inventáři, false pokud není v inventáři.
*/
public boolean obsahujeVec(String nazev)
{
return seznamVeci.containsKey(nazev);
}
/**
* Vrací odkaz na požadovanou věc.
* @param String název věci
* @return Vec
*/
public Vec getVec(String nazev)
{
return seznamVeci.get(nazev);
}
@Override
public int getCapacity()
{
return kapacita;
}
@Override
public Collection<Vec> getItems()
{
return seznamVeci.values();
}
}
DAO课程
package rest_3;
import java.sql.SQLException;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@Path("/dataservice")
@Produces({"application/xml", "application/json"})
@Consumes({"application/xml", "application/json"})
public class DataService {
private ApplicationContext context = new ClassPathXmlApplicationContext("rest_3/servicebean.xml");
private DAO dao = (DAO) context.getBean("daoBean");
public DataService(DAO dao) {
}
@GET
@Path("/location/{id}")
public Location getLocation(@PathParam("id") int id) throws SQLException {
Location loc = dao.getLocation(id);
if (loc == null) {
ResponseBuilder builder = Response.status(Status.BAD_REQUEST);
builder.type("application/xml");
builder.entity("<error>Location Not Found</error>");
throw new WebApplicationException(builder.build());
}
return loc;
}
@POST
@Path("/location")
public Response addLocation(Location loc) throws SQLException {
if(loc == null)
return Response.status(Status.BAD_REQUEST).build();
dao.addLocation(loc);
return Response.ok().build();
}
@DELETE
@Path("/location/{id}")
public Response deleteLocation(@PathParam("id") int id) throws SQLException {
Location loc = dao.getLocation(id);
if(loc == null)
return Response.status(Status.BAD_REQUEST).build();
dao.deleteLocation(id);
return Response.ok().build();
}
@PUT
@Path("/location")
public Response updateLocation(Location loc) throws SQLException {
if(dao.getLocation(loc.getId()) == null)
return Response.status(Status.BAD_REQUEST).build();
dao.updateLocation(loc);
return Response.ok().build();
}
@DELETE
@Path("/location")
public void dropTable() throws SQLException {
dao.dropTable();
}
}
服务和DAO bean。
package rest_3;
import java.sql.*;
import org.apache.derby.jdbc.EmbeddedDataSource;
public class DAO {
private static Connection conn;
private static Statement statement;
private static PreparedStatement prep;
public DAO() throws SQLException {
this.load();
}
public void load() throws SQLException {
EmbeddedDataSource ds = new EmbeddedDataSource();
ds.setDatabaseName("derbyDB");
ds.setCreateDatabase("create");
conn = ds.getConnection();
statement = conn.createStatement();
statement.execute("create table location(id int, country varchar(40))");
statement.execute("insert into location values(1, 'MEXICO')");
statement.execute("insert into location values(2, 'SPAIN')");
statement.execute("insert into location values(3, 'UK')");
statement.execute("insert into location values(4, 'ITALY')");
statement.execute("insert into location values(5, 'JAPAN')");
}
public Location getLocation(int id) throws SQLException {
ResultSet rs = statement.executeQuery("select from location where id = " + id);
rs.next();
return new Location(rs.getInt("id"), rs.getString("country"));
}
public void addLocation(Location loc) throws SQLException{
int id = loc.getId();
String country = loc.getCountry();
prep = conn.prepareStatement("insert into location values(?,?)");
prep.setInt(1, id);
prep.setString(2, country);
prep.execute();
}
public void deleteLocation(int id) throws SQLException{
statement = conn.createStatement();
statement.executeUpdate("delete from location where id = " + id);
}
public void updateLocation(Location loc) throws SQLException {
int id = loc.getId();
String country = loc.getCountry();
statement = conn.createStatement();
statement.execute("update location set country = " + country + " where id = " + id);
}
public void dropTable() throws SQLException {
statement = conn.createStatement();
statement.execute("drop table location");
}
}
服务bean配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataService" class="rest_3.DataService">
<constructor-arg ref ="daoBean"/>
</bean>
<bean id="daoBean" class="rest_3.DAO">
</bean>
</beans>
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxrs:server id="DataService" address="/">
<jaxrs:features>
<cxf:logging/>
</jaxrs:features>
<jaxrs:serviceBeans>
<ref bean="dataService" />
</jaxrs:serviceBeans>
</jaxrs:server>
</beans>
堆栈追踪:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/beans.xml
classpath:rest_3/servicebean.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
答案 0 :(得分:2)
来自setCreateDatabase()
的Javadoc(强调我的):
参数:
create - 如果设置为字符串&#34; create&#34;,此数据源将尝试创建databaseName, 的新数据库,或者如果该名称已存在,则启动数据库 强>
因此,第一次运行代码时,将创建数据库并创建表。第二次没有重新创建数据库,create table
失败,因为它已经存在。
在DAO的构造函数中创建数据库和表是非常糟糕的代码味道。如果确实必须这样做,请确保在尝试创建数据库之前删除数据库。如果这不适用于您的设计,那么您刚刚发现为什么在构造函数中创建数据库是个坏主意。
答案 1 :(得分:0)
我刚删除了这一行,现在工作正常。
statement.execute("create table location(id int, country varchar(40))");