2015-02-10 60 views
0

大家好,我正在嘗試使用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美元的當前預算。如果我離開我的程序並手動添加一個條目到預訂表中,然後讓我的程序再次讀取預訂表,數量會增加/減少。但是,如果我現在改變其中一個價格並讓程序再次讀取所有未更新的預訂。
因此,在更新條目時似乎存在問題,但在將某些內容添加到表中時似乎存在問題。

回答

0

哦,我的。有這麼多錯誤的事情。我們先解決你的問題。您的formbean實例化的IP值爲192.168.178.21。您可以在JSP中使用此方法使用方法cjc.find_XML(Cardreader.class, readerIP);查找記錄。你正在通過IP查找而不是ID。您更改ID並不重要。這就是爲什麼結果是一樣的。

關於代碼本身

  • 切勿使用JSP代碼內。 JSP是一個視圖。如果可以的話,根本不要使用JSP。使用HTML和模板引擎(如Velocity)或Angular等框架,將數據綁定到HTML元素而不需要更多代碼。

  • 你的里程可能會有所不同,但我發現codegen(就像你爲web服務客戶端所做的那樣)和大量的其他框架只會傾向於你想要做的事情。您正在調用一個調用服務器端REST客戶端的JSP來查找數據庫中的值;然後編譯這個怪物並動態運行它,只是爲了向客戶端轉發成功。

  • 請看看AJAX請求以及Web框架如何實現它們。你會節省很多時間。

+0

對不起,但我不完全明白你的意思。我想用id:192.168.178.21來查找讀者,然後從這個1004中提取cardid。當我在數據庫中將ID:1004從讀取器:192.168.178.21更改爲1002時,當程序在後臺運行時,我希望我的程序找到1002,如果我再次詢問,但是它仍然會讓我退回1004。當然還是一樣的。 – CodeHard 2015-02-10 19:56:35

相關問題