大家好,我正在嘗試使用REST Webservice與數據庫進行通信。 對於這個項目,我使用Netbeans 8.1,Struts 1.3和REST Webservice,編程語言是Java。REST Webserivce在數據庫更改後不會更新
我有一個更大的項目,我正在處理,並且存在問題。它不會在運行時識別數據庫中的更改。
數據庫中有一張名爲'cardreader'的表格和一張名爲'chipcards'的表格。讀卡器有一個ID,芯片卡ID爲外鍵和時間戳。芯片卡有一個ID,一個權限ID,一個校驗和和一個時間戳。
讀卡器:
+----------------+---------+-------------------------+
| reader_id | card_id | ts_lastupdate |
+----------------+---------+-------------------------+
| 192.168.178.21 | 1004 | 2015-02-08 20:14:25.401 |
+----------------+---------+-------------------------+
芯片卡:
+------+---------------+----------------+-------------------------+
| id | permission_id | checksum | ts_lastupdate |
+------+---------------+----------------+-------------------------+
| 1002 | 1 | 20141106142003 | 2015-01-22 22:02:50.956 |
| 1003 | 1 | 20141022002939 | 2015-01-22 22:03:00.469 |
| 1004 | 1 | 20141022210457 | 2015-01-22 22:03:13.108 |
| 1005 | 2 | 20141022002737 | 2015-01-22 22:03:17.336 |
| 1006 | 1 | 20141022002736 | 2015-01-22 22:03:25.968 |
| 1007 | 3 | 20141029163510 | 2015-01-22 22:03:29.645 |
+------+---------------+----------------+-------------------------+
在我的計劃,我可以進入 'reader_id',然後在數據庫中查找。如果找到reader_id,我將找回存儲'card_id'的Cardreader對象。
問題是,如果我啓動程序並輸入readerid,我會找回匹配的芯片卡,但是如果我然後在數據庫中更改cardreader表中的'card_id'(假設爲1002),程序仍會返回1004.
正如在乞討中提到的,我使用REST Webservices和Netbeans。藉助Netbeans,您可以生成「從數據庫獲取REST風格的Web服務」,並從FacadeREST類生成「Java Jersey客戶端」。
在這裏,你可以看一下類
AbstractFacade
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.accounting.service;
import java.util.List;
import javax.persistence.EntityManager;
/**
*
* @author Tobias
*/
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public void create(T entity) {
getEntityManager().persist(entity);
}
public void edit(T entity) {
getEntityManager().merge(entity);
}
public void remove(T entity) {
getEntityManager().remove(getEntityManager().merge(entity));
}
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
public List<T> findAll() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return getEntityManager().createQuery(cq).getResultList();
}
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0] + 1);
q.setFirstResult(range[0]);
return q.getResultList();
}
public int count() {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
cq.select(getEntityManager().getCriteriaBuilder().count(rt));
javax.persistence.Query q = getEntityManager().createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
}
}
CardreaderFacade
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.accounting.service;
import com.accounting.Cardreader;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
/**
*
* @author Tobias
*/
@javax.ejb.Stateless
@Path("com.accounting.cardreader")
public class CardreaderFacadeREST extends AbstractFacade<Cardreader> {
@PersistenceContext(unitName = "WebApplication1PU")
private EntityManager em = Persistence.createEntityManagerFactory("WebApplication1PU").createEntityManager();
public CardreaderFacadeREST() {
super(Cardreader.class);
}
@POST
@Override
@Consumes({"application/xml", "application/json"})
public void create(Cardreader entity) {
super.create(entity);
}
@PUT
@Path("{id}")
@Consumes({"application/xml", "application/json"})
public void edit(@PathParam("id") String id, Cardreader entity) {
super.edit(entity);
}
@DELETE
@Path("{id}")
public void remove(@PathParam("id") String id) {
super.remove(super.find(id));
}
@GET
@Path("{id}")
@Produces({"application/xml", "application/json"})
public Cardreader find(@PathParam("id") String id) {
return super.find(id);
}
@GET
@Override
@Produces({"application/xml", "application/json"})
public List<Cardreader> findAll() {
return super.findAll();
}
@GET
@Path("{from}/{to}")
@Produces({"application/xml", "application/json"})
public List<Cardreader> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
return super.findRange(new int[]{from, to});
}
@GET
@Path("count")
@Produces("text/plain")
public String countREST() {
return String.valueOf(super.count());
}
@Override
protected EntityManager getEntityManager() {
return em;
}
}
CardreaderJerseyClient
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.accountng.client;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.WebTarget;
/**
* Jersey REST client generated for REST resource:CardreaderFacadeREST
* [com.accounting.cardreader]<br>
* USAGE:
* <pre>
* CardreaderJerseyClient client = new CardreaderJerseyClient();
* Object response = client.XXX(...);
* // do whatever with response
* client.close();
* </pre>
*
* @author Tobias
*/
public class CardreaderJerseyClient {
private WebTarget webTarget;
private Client client;
private static final String BASE_URI = "http://localhost:8081/WebApplication1/webresources";
public CardreaderJerseyClient() {
client = javax.ws.rs.client.ClientBuilder.newClient();
webTarget = client.target(BASE_URI).path("com.accounting.cardreader");
}
public String countREST() throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path("count");
return resource.request(javax.ws.rs.core.MediaType.TEXT_PLAIN).get(String.class);
}
public void edit_XML(Object requestEntity, String id) throws ClientErrorException {
webTarget.path(java.text.MessageFormat.format("{0}", new Object[]{id})).request(javax.ws.rs.core.MediaType.APPLICATION_XML).put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_XML));
}
public void edit_JSON(Object requestEntity, String id) throws ClientErrorException {
webTarget.path(java.text.MessageFormat.format("{0}", new Object[]{id})).request(javax.ws.rs.core.MediaType.APPLICATION_JSON).put(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_JSON));
}
public <T> T find_XML(Class<T> responseType, String id) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("{0}", new Object[]{id}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType);
}
public <T> T find_JSON(Class<T> responseType, String id) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("{0}", new Object[]{id}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
public <T> T findRange_XML(Class<T> responseType, String from, String to) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("{0}/{1}", new Object[]{from, to}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType);
}
public <T> T findRange_JSON(Class<T> responseType, String from, String to) throws ClientErrorException {
WebTarget resource = webTarget;
resource = resource.path(java.text.MessageFormat.format("{0}/{1}", new Object[]{from, to}));
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
public void create_XML(Object requestEntity) throws ClientErrorException {
webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_XML).post(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_XML));
}
public void create_JSON(Object requestEntity) throws ClientErrorException {
webTarget.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(javax.ws.rs.client.Entity.entity(requestEntity, javax.ws.rs.core.MediaType.APPLICATION_JSON));
}
public <T> T findAll_XML(Class<T> responseType) throws ClientErrorException {
WebTarget resource = webTarget;
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_XML).get(responseType);
}
public <T> T findAll_JSON(Class<T> responseType) throws ClientErrorException {
WebTarget resource = webTarget;
return resource.request(javax.ws.rs.core.MediaType.APPLICATION_JSON).get(responseType);
}
public void remove(String id) throws ClientErrorException {
webTarget.path(java.text.MessageFormat.format("{0}", new Object[]{id})).request().delete();
}
public void close() {
client.close();
}
}
層
的index.jsp
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>
<html:form action="/checkCard">
<html:text property="name" value="192.168.178.21">Cardreader IP</html:text>
<html:submit property="submitValue">SEND</html:submit>
</html:form>
**checkCard**
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.tobias.actions;
import com.accounting.Cardreader;
import com.accounting.Chipcards;
import com.accountng.client.CardreaderJerseyClient;
import com.tobias.beans.infoBean;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
/**
*
* @author Tobias
*/
public class checkCard extends org.apache.struts.action.Action {
/* forward name="success" path="" */
private static final String SUCCESS = "success";
/**
* This is the action called from the Struts framework.
*
* @param mapping The ActionMapping used to select this instance.
* @param form The optional ActionForm bean for this request.
* @param request The HTTP Request we are processing.
* @param response The HTTP Response we are processing.
* @throws java.lang.Exception
* @return
*/
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String readerIP;
infoBean formBean = (infoBean) form;
readerIP = formBean.getName();
System.out.println("READER IP: " + readerIP);
CardreaderJerseyClient cjc = new CardreaderJerseyClient();
if(cjc == null){
System.out.println("JERSEYCLIENT IST NULL");
}
Cardreader reader = cjc.find_XML(Cardreader.class, readerIP);
if(reader != null){
System.out.println("READER IP = " + reader.getReaderId());
Chipcards card = reader.getCardId();
if(card != null){
System.out.println("CHIPCARD ID = " + card.getId().toString());
} else {
System.out.println("No card found);
}
} else {
System.out.println("No reader found");
}
return mapping.findForward(SUCCESS);
}
}
的struts-config
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean name="infoBean" type="com.tobias.beans.infoBean"/>
</form-beans>
<global-exceptions>
</global-exceptions>
<action-mappings>
<action name="infoBean" path="/checkCard" scope="request" type="com.tobias.actions.checkCard" validate="false">
<forward name="success" path="/index.jsp"/>
</action>
<action path="/Welcome" forward="/welcomeStruts.jsp"/>
</action-mappings>
<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
<message-resources parameter="com/myapp/struts/ApplicationResource"/>
<!-- ========================= Tiles plugin ===============================-->
<!--
This plugin initialize Tiles definition factory. This later can takes some
parameters explained here after. The plugin first read parameters from
web.xml, thenoverload them with parameters defined here. All parameters
are optional.
The plugin should be declared in each struts-config file.
- definitions-config: (optional)
Specify configuration file names. There can be several comma
separated file names (default: ??)
- moduleAware: (optional - struts1.1)
Specify if the Tiles definition factory is module aware. If true
(default), there will be one factory for each Struts module.
If false, there will be one common factory for all module. In this
later case, it is still needed to declare one plugin per module.
The factory will be initialized with parameters found in the first
initialized plugin (generally the one associated with the default
module).
true : One factory per module. (default)
false : one single shared factory for all modules
- definitions-parser-validate: (optional)
Specify if xml parser should validate the Tiles configuration file.
true : validate. DTD should be specified in file header (default)
false : no validation
Paths found in Tiles definitions are relative to the main context.
-->
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>
<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>
後記
如果你還在讀書:謝謝!我知道我已經發布了很多代碼,我不確定我的描述是否足夠了解所有內容,但我是德語,請耐心等待。
我對這個REST的東西有一些小的知識,但我還不完全理解最新的情況。總結起來,我不明白爲什麼我的程序讀取數據庫的第一個card_id表單正確,但是當我手動更改數據庫中的值並且程序仍在運行時,它不會更新。
再次感謝您通過這段文字的讀者。如果你有任何想法可能是,或者如果您需要進一步的解釋只是讓我知道:)
編輯
好於我已經注意到一些更多的信息。該計劃還有能力創建預訂。因此,客戶可以購買一些東西或在他的芯片卡上添加資金。因此,有一張名爲「預訂」的表格,其中存儲了ID,客戶ID,價格和bookingtyp。
我已經開始了我的計劃,讓它讀取所有預訂並創建300美元的當前預算。如果我離開我的程序並手動添加一個條目到預訂表中,然後讓我的程序再次讀取預訂表,數量會增加/減少。但是,如果我現在改變其中一個價格並讓程序再次讀取所有未更新的預訂。
因此,在更新條目時似乎存在問題,但在將某些內容添加到表中時似乎存在問題。
對不起,但我不完全明白你的意思。我想用id:192.168.178.21來查找讀者,然後從這個1004中提取cardid。當我在數據庫中將ID:1004從讀取器:192.168.178.21更改爲1002時,當程序在後臺運行時,我希望我的程序找到1002,如果我再次詢問,但是它仍然會讓我退回1004。當然還是一樣的。 – CodeHard 2015-02-10 19:56:35