REST Web服务不会在数据库更改后进行更新

时间:2015-02-10 18:40:52

标签: java web-services postgresql rest netbeans

大家好我正在尝试使用REST WEbservice与数据库进行通信。 对于这个项目,我使用的是Netbeans 8.1,Struts 1.3和REST Webservice,编程语言是Java。

我有一个更大的项目,我正在努力,有一个问题。在运行时期间无法识别数据库中的更改。
数据库中有一个名为'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,我将返回一个Cardreader对象,其中存储了'card_id'。
问题是,如果我启动程序并输入一个阅读器,我将返回匹配的芯片卡,但是如果我然后从数据库中更改了cardreader表中的'card_id'(比如1002),程序仍然返回1004。
正如乞讨中所提到的,我正在使用REST Webservices和Netbeans。使用Netbeans,您可以从“数据库”生成“RESTful 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,价格和预订单。
我已经启动了我的程序并让它读取所有预订并创建客户的当前预算,如300 $。如果我让我的程序继续运行并手动在预订表中添加一个条目,然后让我的程序再次读取预订表,那么金额会增加/减少。但是,如果我现在更改其中一个价格,让程序再次阅读所有预订,它不会更新。
因此,在更新条目时似乎存在问题,但在向表中添加内容时却没有问题。

2 个答案:

答案 0 :(得分: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服务客户端所拥有的那样)和许多其他框架只会覆盖您尝试做的事情。您正在调用一个JSP,该JSP调用服务器端的REST客户端来查找数据库中的值;然后编译这个怪物并动态运行它只是为了向客户端转发成功。

  • 请查看AJAX请求以及Web框架如何实现它们。你会节省很多时间。

答案 1 :(得分:0)

回答这个问题我来晚了,但正确的答案总是有帮助的。

在您的presistance.xml文件中,将shared-cache-mode更改为NONE

相关问题