Recurso de serviço web (REST) chamando BO

6 respostas
J

Olá pessoal,

Possuo uma aplicação Spring/Ibatis que funciona sem problema. requisição é passada ao controller, que invoca um BO, que invoca um DAO que devolve os dados ao BO que trata os mesmos e devolve ao contoller para carregar na view, a grosso modo é isso que acontece.

Eu gostaria de criar um serviço WEB que se comunicasse com essa aplicação para apresentar os dados, o serviço seria um serviço REST.

mas não sei como fazer, imaginei ter uma instância do meu BO no serviço REST e ao receber uma solicitação encaminho para ele uma requisição que fará a comunicação com o DAO e me retornará os dados, é esse o raciocínio correto? Alguém sugere algo? Existe alguma configuração adicional a ser feita? Injeção de dependência ou algo do tipo?

Obrigado.

6 Respostas

Alexandre_Saudate

Acho BO uma heresia. Fora isso, seria interessante você encarar seu serviço REST como um controller, ou seja, ele faria a mesma coisa que seu controller, mas com uma perspectiva mais orientada a recursos e REST. Se tiver dúvidas sobre como fazer, eu tenho um bootstrap de REST com Jersey e Spring já pronto no meu github: https://github.com/alesaudate/kickstart-springjerseyhibernate .

[]'s

J

valeu asaudate, sempre salvando a pátria! rsrsrs…

vou baixar o projeto e tentar implementar!

Obrigado, qualquer coisa posto aqui.

J

Criei mas deu um erro.

vou postar o erro e minha classe de serviço.

erro:

INFO: Scanning for root resource and provider classes in the Web app resource paths:
  /WEB-INF/lib
  /WEB-INF/classes
INFO: Root resource classes found:
  class com.kohlerapp.resources.ProductFacadeRest
INFO: Provider classes found:
  class org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider
  class org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper
  class org.codehaus.jackson.jaxrs.JsonParseExceptionMapper
  class org.codehaus.jackson.jaxrs.JacksonJsonProvider
INFO: CDI support is enabled
INFO: Initiating Jersey application, version 'Jersey: 1.8 06/24/2011 12:17 PM'
GRAVE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container

Serviço

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kohlerapp.resources;

import com.gorilla.domain.Product;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import com.app.bo.impl.webServiceBOImpl;
import com.app.bo.WebServiceBO;
import java.util.List;
import javax.ws.rs.Produces;

@Path("/ws")
public class ProductFacadeRest {

    private final Logger LOGGER = Logger.getLogger(ProductFacadeRest.class.getName());
    
    @Inject
    private webServiceBOImpl _webServiceBO;

    @GET
    @Produces({"application/xml", "application/json"})
    public List<Product> productsList() {
        return this._webServiceBO.listProductsByRecordType("Product");
        //return "Hello";
    }
}

Minha classe BO

package com.app.bo.impl;

import com.gorilla.bo.BusinessServiceUtils;
import com.gorilla.bo.Option;
import com.gorilla.domain.*;
import com.app.bo.WebServiceBO;
import com.lelak.onlinecatalog.dao.ProductDao;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Required;

/**
 * Business object that provides AbstractProduct management functionalities.
 */
public class webServiceBOImpl implements WebServiceBO, InitializingBean {

    protected Log _log = LogFactory.getLog(webServiceBOImpl.class);
    private ProductDao _productDao;
    private BusinessServiceUtils _businessServiceUtils;
    private List<String> _orderedByPositionOptions;
    private Map<String, List<String>> _ignoredProductFilters = new HashMap();

    

    /**
     * Finds Products by a general query.
     * This will look for products with the received query
     * as a product type, collection, construction type or parentItemNumber.
     * @param query the query
     * @param attributesToRetrieve the attributes names to retrieve
     * @return the resulting List of Products
     */
    public List<Product> listProductsByRecordType(String recordType) {

        if (StringUtils.isBlank(recordType)) {
            String message = "Error, the query can not be null or an empty string";
            _log.error(message);
            throw new IllegalArgumentException(message);
        }

        return this.removeIgnoredProducts(getProductDao().getProductsByRecordType(recordType));
    } 
    
       /**
     * Finds Products, attributes, copy and related by record_type
     * @param record_type
     * @return the resulting List of Products, copy, attributes, related products
     */
    public List<Product> listProductsAndRelatedByRecordType(String recordType) {

        if (StringUtils.isBlank(recordType)) {
            String message = "Error, the query can not be null or an empty string";
            _log.error(message);
            throw new IllegalArgumentException(message);
        }

        return this.removeIgnoredProducts(getProductDao().getProductsAndRelatedByRecordType(recordType));
    } 




    private List<Option> convertMapToOptionsList(Map<String, String> optionsMap) {
        List<Option> options = new ArrayList();
        Option option;
        for (Map.Entry<String, String> entry : optionsMap.entrySet()) {
            if (StringUtils.isNotBlank(entry.getKey())
                    && StringUtils.isNotBlank(entry.getValue())) {
                option = new Option();
                option.setName(entry.getKey());
                option.setValue(entry.getValue());
                options.add(option);
            }
        }
        return options;
    }

    private List<ProductAttribute> convertMapToProductAttributeList(
            Map<String, String> optionsMap) {
        List<ProductAttribute> attributesList = new ArrayList();

        AttributeValue value;
        ProductAttribute attribute;

        for (Map.Entry<String, String> entry : optionsMap.entrySet()) {
            if (StringUtils.isNotBlank(entry.getKey())
                    && StringUtils.isNotBlank(entry.getValue())) {
                value = new AttributeValue();
                value.setValue(entry.getValue());

                attribute = new ProductAttribute();
                attribute.setName(entry.getKey());
                attribute.getValues().add(value);

                attributesList.add(attribute);
            }
        }
        return attributesList;
    }

    /**
     * Sets the ProductDao.
     * @param productDao the _productDao to set
     */
    @Required
    public void setProductDao(ProductDao productDao) {
        this._productDao = productDao;
    }



    /**
     * Sets the Gorilla BusinessServiceUtils required for the products details.
     * @param businessServiceUtils the _businessServiceUtils to set
     */
    @Required
    public void setBusinessServiceUtils(BusinessServiceUtils businessServiceUtils) {
        this._businessServiceUtils = businessServiceUtils;
    }


    /**
     * Gets the ProductDao.
     * @return the _productDao
     */
    public ProductDao getProductDao() {
        return _productDao;
    }


    /**
     * Gets the BusinessServiceUtils.
     * @return the _businessServiceUtils
     */
    public BusinessServiceUtils getBusinessServiceUtils() {
        return _businessServiceUtils;
    }

    /**
     * Gets the ordered by position options.
     * @return the _orderedByPositionOptions
     */
    public List<String> getOrderedByPositionOptions() {
        return _orderedByPositionOptions;
    }

    /**
     * Sets the ordered by position options.
     * This is used by getSectionFilters to determine which filters will be
     * retrieved and ordered by the position field.
     * @param orderedByPositionOptions the _orderedByPositionOptions to set
     */
    public void setOrderedByPositionOptions(List<String> orderedByPositionOptions) {
        this._orderedByPositionOptions = orderedByPositionOptions;
    }

    /**
     * Gets the _ignoredProductFilters.
     * @return the _ignoredProductFilters
     */
    public Map<String, List<String>> getIgnoredProductFilters() {
        return this._ignoredProductFilters;
    }

    /**
     * Sets the _ignoredProductFilters.
     * @param ignoredProductFilters the _ignoredProductFilters to set
     */
    public void setIgnoredProductFilters(Map<String, List<String>> ignoredProductFilters) {
        this._ignoredProductFilters = ignoredProductFilters;
    }

    /**
     * Filters products that matches the configuration on _ignoredProductFilters.
     * @param products the products list
     * @return a products list without the filtered products
     */
    protected List<Product> removeIgnoredProducts(List<Product> products) {
        List<Product> clearedProducts = new ArrayList();
        boolean matches;

        for (Product product : products) {
            matches = false;
            for (ProductAttribute productAttribute : product.getAttributes()) {
                if (this._ignoredProductFilters.containsKey(productAttribute.getName())) {
                    matches = this.checkValuesAgainstIgnoredOnes(
                            productAttribute, this._ignoredProductFilters
                            .get(productAttribute.getName()));
                    break;
                }
            }

            if (!matches) {
                clearedProducts.add(product);
            }
        }

        return clearedProducts;
    }

    /**
     * Checks if a given productAttribute values matches against a list of regular expressions.
     * @param productAttribute the ProductAttribute to check
     * @param regexes the regex list
     * @return true if match, false otherwise
     */
    protected boolean checkValuesAgainstIgnoredOnes(
            ProductAttribute productAttribute, List<String> regexes) {
        for (AttributeValue value : productAttribute.getValues()) {
            for (String regex : regexes) {
                if (value.getValue() != null && value.getValue().matches(regex)) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Replace characters and strings from product attributes
     * based on the replace Map.
     * @param product to be escaped
     * @return a escaped product;
     */
    
     public Product replaceString(Product product){

        return product;

     }
     
     
    
     
}

É esse o caminho? Onde posso ter errado?

Alexandre_Saudate

Bom, essa linha:

GRAVE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container

indica que uma RuntimeException foi lançada em algum ponto. Se você subir a aplicação pela IDE, em modo debug, deve ser possível habilitar o debugger para capturar essa exceção e, assim, você pode checar melhor o que aconteceu.

[]'s

J

Certo, mas em tese está certo o caminho que estou tentando percorrer?

Alexandre_Saudate

Não tenho como saber. Não sei em que momento aconteceu o erro, nem como estão as configurações, nem o contêiner em que está rodando. Só o que sei é que o CDI está configurado.

Criado 13 de março de 2012
Ultima resposta 13 de mar. de 2012
Respostas 6
Participantes 2