0

I have an app that needs to show a map with custom points that are on a database. For the frontend I have a very simple map that tries to communicate with a webservice that reads the points and generates a JSON string. The service is working well (is it developed on jboss), and the map shows the points if I disable CORS (I'm working with Chrome with the extension to disable CORS). If not, I receive the error "No 'Access-Control-Allow-Origin' header is present on the requested resource.". But I want to repair this and have the app fully operational.

I added the headers on the java service, but I don't know well if I have to add this on the Angular.app.

Code for DispatcherServlet.java (the service)

package com.parkfind.server;

import java.io.IOException;
import java.util.ArrayList;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.parkfind.servicios.AppServiceRemote;

@WebServlet("/DispatcherServlet")
public class DispatcherServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public static final Logger LOG = Logger.getLogger(DispatcherServlet.class);

    @EJB
    AppServiceRemote servicio;

    public DispatcherServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        LOG.info("Accedido a Servlet");
        String accion = request.getParameter("accion");
        String datosJSON = new String();

        try {

            if(accion.equals("getDatosUsuario"))
            {
                int id = Integer.parseInt(request.getParameter("idUser").equals("")?"0":request.getParameter("idUser"));
                String login = request.getParameter("login");
                String nombre = request.getParameter("nombres");
                String apPaterno = request.getParameter("ap_parterno");
                String apMaterno = request.getParameter("ap_materno");

                datosJSON = servicio.getDatosUsuario(id, login, nombre, apPaterno, apMaterno);
            }
            else if(accion.equals("borrarUsuario"))
            {
                int idUsuario = Integer.parseInt(request.getParameter("idUsuario"));
                datosJSON = servicio.borrarUsuario(idUsuario);
            }
            else if(accion.equals("ingresarUsuario"))
            {
                String username = request.getParameter("username");
                String password = request.getParameter("password");
                String nombre = request.getParameter("nombre");
                String ap_parterno = request.getParameter("ap_paterno");
                String ap_marterno = request.getParameter("ap_materno");
                String email = request.getParameter("email");
                int fono = Integer.parseInt(request.getParameter("fono"));
                String direccion = request.getParameter("direccion");
                String comuna = request.getParameter("comuna");

                datosJSON = servicio.ingresarUsuario(username,password, nombre,ap_parterno ,ap_marterno ,email, fono, direccion,comuna);
            }
            else if(accion.equals("ingresarEstacionamiento"))
            {
                String direccion = request.getParameter("direccion");
                int comuna = Integer.parseInt(request.getParameter("comuna"));
                double coordenada_x = Double.parseDouble(request.getParameter("x"));
                double coordenada_y = Double.parseDouble(request.getParameter("y"));
                int dimension = Integer.parseInt(request.getParameter("dimension"));
                String tipo = request.getParameter("tipo");
                int modalidad = Integer.parseInt(request.getParameter("modalidad"));
                int costo = Integer.parseInt(request.getParameter("costo"));
                int idUser = Integer.parseInt(request.getParameter("idUser"));

                datosJSON = servicio.ingresarEstacionamiento(direccion, comuna, coordenada_x, coordenada_y, dimension, tipo, modalidad, costo, idUser);
            }
            else if(accion.equals("listarEstacionamientos"))
            {
                datosJSON = servicio.listarEstacionamientos();
            }
            else
            {
                LOG.error("Error: Acción no existe");
                throw new Exception("Error: Acción no existe");
            }

            response.setContentType("application/json");
            response.setCharacterEncoding("utf8");
            response.setHeader("cache-control", "no-cache, no-store");
            response.setHeader("Pragma", "no-cache");

            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Content-Type");

            response.getWriter().write(datosJSON);

        } catch (Exception e) {
            LOG.error("Error en invocacion EJB: " + e.getMessage());
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

maps.js code

//Angular App Module and Controller
      var sampleApp = angular.module('mapsApp', []);
      sampleApp.controller('MapCtrl', function ($scope, $http) {

        var mapOptions = {
              zoom: 12,
              center: new google.maps.LatLng(-33.033333333333,-71.533333333333),
              mapTypeId: google.maps.MapTypeId.ROADMAP
          }

          $scope.map = new google.maps.Map(document.getElementById('map'), mapOptions);

          $scope.markers = [];

          var infoWindow = new google.maps.InfoWindow();

          var createMarker = function (info){

              est = JSON.parse(info);

              var marker = new google.maps.Marker({
                  map: $scope.map,
                  position: new google.maps.LatLng(est.coordenada_x, est.coordenada_y),
                  title: "$ " + est.costo
              });

              marker.content = '<div class="infoWindowContent">' + est.direccion + '</div>';

              google.maps.event.addListener(marker, 'click', function(){
                  infoWindow.setContent('<h2>' + marker.title + '</h2>' + marker.content);
                  infoWindow.open($scope.map, marker);
              });

              $scope.markers.push(marker);

          }


        $scope.openInfoWindow = function(e, selectedMarker){
              e.preventDefault();
              google.maps.event.trigger(selectedMarker, 'click');
          }

        // Obteniendo estacionamientos desde la BD
        var estacionamientos = null;

        $http.get('http://parkfind.ddns.net:8080/parkfind-web/DispatcherServlet?accion=listarEstacionamientos').success(function(data,{}, header) {
            estacionamientos = data;
    console.log(header);
    console.log(estacionamientos);
          for (i = 0; i < estacionamientos.length; i++){
              createMarker(estacionamientos[i]);
          }
        });
      });

mapa2.html (in where I show the map)

<!DOCTYPE html>
<html ng-app="mapsApp">
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" href="../css/maps.css">
<script
  src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script
  src="http://maps.googleapis.com/maps/api/js?sensor=false&language=en&key=AIzaSyAqHxheQT_oNchlOOqL2fvwKO7lEnS-TPc"></script>
  <script type="text/javascript" src="../js/maps.js"></script>
</head>
<body>
<div ng-controller="MapCtrl">
    <div id="map"></div>
</div>
</body>
</html>

Service: http://parkfind.ddns.net:8080/parkfind-web/DispatcherServlet?accion=listarEstacionamientos Map Frontend: http://parkfind.ddns.net/web_SW/pages/mapa2.html

I think the problem resides on the Angular app, because the servlet sends the header if I see the Chrome Network tab. But I'm lost. Thanks in advance!

1 Answers1

0

I have never really done any JBoss development before, but am aware of the CORS workflow. The browser will send an OPTIONS HTTP request to the endpoint before it makes the GET request. You could try adding the following method to your DispatcherServlet class to respond to the OPTIONS call. The browser should then be happy to make the CORS request.

protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");   
    response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    response.setStatus(HttpServletResponse.SC_OK);
}

Note: There may be better ways of doing\configuring this that does not require you to respond to the CORS OPTIONS call in your application code (Tomcat provides a org.apache.catalina.filters.CorsFilter that can be used to automatically do this for you)

Note 2: If you plan on doing "credentialed" requests you'll need to return the exact host in Access-Control-Allow-Origin instead of *. See this stack overflow answer or Mozilla Documentation

Community
  • 1
  • 1
twomarktwo
  • 332
  • 1
  • 11