Problemas com select dinamico usando ajax e json

3 respostas
I

Boa tarde pessoal, estou com um problema chato e não estou sabendo resolver.

Estou fazendo um combo de Estado que ao ter um escolhido carrega um outro combo com as Cidades daquele Estado.
Eu já tinha feito algo parecido em um outro projeto e resolvi reaproveitar.

no script .js eu faço uma requisição ajax para uma Servlet passando como parâmetro o uf do estado selecionado.
ele entra na Servlet direitinho, pega as Cidades que pertencem ao Estado selecionado, só que quando eu vou iterar
o List para adicionar em um JsonArray ele simplesmente lança uma exceção que eu não consigo entender.

O que eu realmente acho estranho é que no outro sistema está funcionando perfeitamente. Se alguém puder me ajudar
a resolver esse problema ficarei muito grato.

Segue a Servlet e a exceção que estourou.

public class CarregarCidades extends HttpServlet {

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = null;

    String estado = request.getParameter("estado");
    List<Cidade> listaCidades = null;
    JSONArray jsonArray = null;
    JSONObject object = null;

    try {

        out = response.getWriter();

        SessionFactory fabricaSessao = HibernateSessionFactory.getSessionFactory();
        Session sessao = fabricaSessao.openSession();

        Criteria criterio = sessao.createCriteria(Cidade.class);
        criterio.createAlias("estado", "estado");
        criterio.add(Restrictions.eq("estado.sigla", estado));

        listaCidades = criterio.list();
        
        jsonArray = new JSONArray();
        
        if (listaCidades != null) {

            for(Cidade cidade: listaCidades){
                jsonArray.add(cidade); // linha que estoura a exception
            }
            
        }else {
            jsonArray.add("Erro");
        }

    } catch (Exception ex) {
        ex.printStackTrace();
        System.out.println("=====================================================================================================");
        System.out.println(ex.getMessage());
        
        System.out.println("=====================================================================================================");
    } finally {
        out.print(jsonArray);
        out.close();
    }
}

----------------------------------------------------------------------- Exception Lançada --------------------------------------------------------------------------------

net.sf.json.JSONException: There is a cycle in the hierarchy!
at net.sf.json.util.CycleDetectionStrategy$StrictCycleDetectionStrategy.handleRepeatedReferenceAsObject(CycleDetectionStrategy.java:97)
at net.sf.json.JSONObject._fromBean(JSONObject.java:857)
at net.sf.json.JSONObject.fromObject(JSONObject.java:192)
at net.sf.json.JSONArray._processValue(JSONArray.java:2557)
at net.sf.json.JSONArray.processValue(JSONArray.java:2588)
at net.sf.json.JSONArray.addValue(JSONArray.java:2575)
at net.sf.json.JSONArray._fromCollection(JSONArray.java:1082)
at net.sf.json.JSONArray.fromObject(JSONArray.java:145)
at net.sf.json.JSONObject._processValue(JSONObject.java:2749)
at net.sf.json.JSONObject._setInternal(JSONObject.java:2798)
at net.sf.json.JSONObject.setValue(JSONObject.java:1507)
at net.sf.json.JSONObject._fromBean(JSONObject.java:940)
at net.sf.json.JSONObject.fromObject(JSONObject.java:192)
at net.sf.json.JSONObject._processValue(JSONObject.java:2774)
at net.sf.json.JSONObject._setInternal(JSONObject.java:2798)
at net.sf.json.JSONObject.setValue(JSONObject.java:1507)
at net.sf.json.JSONObject._fromBean(JSONObject.java:940)
at net.sf.json.JSONObject.fromObject(JSONObject.java:192)
at net.sf.json.JSONArray._processValue(JSONArray.java:2557)
at net.sf.json.JSONArray.processValue(JSONArray.java:2588)
at net.sf.json.JSONArray.addValue(JSONArray.java:2575)
at net.sf.json.JSONArray.element(JSONArray.java:1751)
at net.sf.json.JSONArray.add(JSONArray.java:1276)
at net.sf.json.JSONArray.add(JSONArray.java:1272)
at br.com.onbudget.cotare.servlet.CarregarCidades.processRequest(CarregarCidades.java:64)
at br.com.onbudget.cotare.servlet.CarregarCidades.doGet(CarregarCidades.java:105)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

There is a cycle in the hierarchy!

3 Respostas

M

Olha, até onde eu sei vc tem que criar um objeto json e adicionar o objeto json no jsonArray, e não o objeto cidade direto no jsonArray… Tem certeza que isso funcionava no outro projeto?

I

Fala Mitidiero, obrigado por ter respondido.

Está funcionando no outro sim, acabei de testar de novo. Eu reutilizei essa servlet.

Para usar jsonObject eu teria que pegar cada objeto cidade e setar nele com uma chave para depois colocar no jsonArray né?

Se eu fizer dessa forma como eu faria para recuperar os dados das cidades na jsp?

Eu precisaria criar um nome de chave diferente para cada jsonObject que eu criasse né?

não tenho muita prática com json.

M

Vamos por partes.

Olha só, pra criar o JSON eu criei uma classe JSON, e coloquei dois métodos, um para gerar uma lista de objetos, outro pra me trazer um objeto.

public class CidadesJSON {

    public static JSONArray geraJSON(List<Cidades> listCidades) {

        try {
            JSONArray a = new JSONArray();

            for(int i = 0; i<listCidades.size();i++) {
                a.put(geraObjeto(listCIdades.get(i)));
            }

            return a;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }

    }
 
    public static JSONObject geraObjeto(Cidades objCidade) {
        try {
            JSONObject objJSON = new JSONObject();
            objJSON.put("id", objCidade.getId());
            objJSON.put("cidade", objCidade.getCidade());
            objJSON.put("idEstados", objCidade.getIdEstados().getId());
            objJSON.put("sigla", objCidade.getIdEstados().getSigla());
            return objJSON;
        } catch (JSONException e) {
            e.printStackTrace();
            return null;
        }
    }
    
}

Depois, lá na minha página web eu utilizava jquery para iterar os resultados, no caso eu passava alguns parâmetros a mais, mas da pra entender abaixo:

function atualizar() {
		
	var d = new Date();
	var t = d.getTime();
	var x = d.getDate();
	where = "";
	limit = 0;
	orderby = "Cidade";
	ascdesc = "";
	$.ajax({
		type : "GET", 
		dataType: "json",
		url : "../Cidades.do?operacao=listar&where="+where+"&limit="+limit+"&orderby="+orderby+"&ascdesc="+ascdesc+"&dht="+t+x,
		// Antes de enviar
		beforeSend: function(){
			// mostro a div loading
			$('#loading').show();
		},
		success : function( txt ){
			
			Linhas = CabecalhoHTML;

			cor = "FFF"

            $.each(txt, function(n) {
			if (cor == "FFF")
				cor = "DDD";
			else
				cor = "FFF";								
				Linhas += "<tr class='linhaTabela' style='background-color:#"+cor+";'>";
				Linhas += "<td align='center'>"+txt[n].id+"</td>";
				Linhas += "<td align='center'>"+txt[n].cidade+"</td>";
				Linhas += "<td align='center'>"+txt[n].sigla+"</td>";
				Linhas += "<td align='center' width='70'><a href='#' title='Editar Cidade' class='editarCidade' id='"+txt[n].id+"'>"
				+ "<img src='../images/icones/edit-256.png' width='32' height='32' alt='Filtar' border='0' />"
				+ "</a></td>";
				Linhas += "<td align='center' width='70'><a href='#' title='Excluir Cidade' class='excluirCidade' id='"+txt[n].id+"'>"
				+ "<img src='../images/icones/cnrdelete-all1-256.png' width='32' height='32' alt='Filtar' border='0' />"
				+ "</a></td>";
				Linhas += "</tr>";  
				listaCidade = txt[n].tamanhojson;
				totalCidade = txt[n].qtdtotal;   
				limitinicio = txt[n].limitinicio;
				limitfinal = txt[n].limitfinal;              
			})

			qtdPaginas = totalCidade/20;
			
			//Pagination Numbers
			
			
			Linhas += "<tr style='line-height:36px; background-color:#84b343; color:#FFF; font-weight:bold;'>";
			Linhas += "<td colspan='3' align='left' style='padding-left:10px; text-align:left'>"
					+ "<ul id=\"pagination\">";
			
			for(i=0; i<=qtdPaginas; i++) {
				z = i+1;
				Linhas += "<li id=\""+i+"\">"+z+"</li>";
			}
					
			limitfinal = limitinicio+20;
			if (limitfinal > totalCidade)
				limitfinal = totalCidade;
				
			Linhas += "</ul>"
					+ "</td>";

			Linhas += "<td colspan='3' align='right' style='padding-right:10px;'>"
					+ "Exibindo: "
					+ limitinicio
					+ " - "
					+ limitfinal
					+ " de "
					+totalCidade
					+" Registros"
					+ "</td>";

			
			Linhas+= "</table></form>";
			$('#loading').fadeOut(500);
			$('#colocaraqui').html(Linhas);
		}
	});

No caso, esse Cidades.do era meu servlet também, que da pra ver abaixo ele:

if (operacao.equals(Operacoes.LISTAR)) {
                String where = request.getParameter("where");
                if (where.equals(""))
                    where = null;
                
                int limit = Integer.parseInt(request.getParameter("limit"));
                limit = limit*Constantes.REGPAG;
                int offset = Constantes.REGPAG;
                
                String orderby = request.getParameter("orderby");
                if (orderby.equals(""))
                    orderby = null;
                String ascdesc = request.getParameter("ascdesc");
                if (ascdesc.equals(""))
                    ascdesc = null;
                
                if(orderby != null)
                    if (ascdesc != null)
                        orderby = orderby + " "+ascdesc;
                

                    out.println(CidadesJSON.geraJSON(cidDAO.fetchAll(where, orderby, limit, offset), cidDAO.totalRegs(null), limit, offset));
                } else if (operacao.equals(Operacoes.BUSCAR)) {
                    Cidades objCidade2 = new Cidades();
                    objCidade2.setId(Integer.parseInt(request.getParameter("id")));
                    objCidade2 = (Cidades) cidDAO.fetchOne(objCidade2);
                    out.println(CidadesJSON.geraObjeto(objCidade2));
                    System.out.println(CidadesJSON.geraObjeto(objCidade2));
                } else if (operacao.equals(Operacoes.ALTERAR)) {
                    Cidades objCidade2 = new Cidades();
                    objCidade2.setId(Integer.parseInt(request.getParameter("txtIdCidades")));
                    objCidade2.setCidade(request.getParameter("txtCidade"));
                    Estados objEstado = new Estados();
                    EstadosDAO estDAO = new EstadosDAO(c);
                    System.out.println(request.getQueryString());
                    objEstado.setId(Integer.parseInt(request.getParameter("txtIdEstados")));
                    objEstado = (Estados) estDAO.fetchOne(objEstado);
                    objCidade2.setIdEstados(objEstado);
                    
                    if (cidDAO.update(objCidade2) > -1)
                        out.println("1##Editado com Sucesso.");
                    else
                        out.println("0##Erro ao Editar Registro.");
                }

Espero que ajude :wink:

Abraços.

(Recomendo fortemente o uso de jquery)

Criado 15 de março de 2012
Ultima resposta 15 de mar. de 2012
Respostas 3
Participantes 2