Я пытаюсь протестировать простой Spring MVC с проектом angular 2, работающим на eclipse.
HTML-страница отображается, но не загружает данные из бэкэнда Spring, есть идеи, почему это происходит?
вывод консоли:
Oct 06, 2017 11:31:22 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.j2ee.server:AngularjsSpringRestExample' did not find a matching property.
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server version: Apache Tomcat/8.0.47
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server built: Sep 29 2017 13:46:41 UTC
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Server number: 8.0.47.0
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: OS Name: Windows 7
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: OS Version: 6.1
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Architecture: amd64
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Java Home: C:\Program Files\Java\jdk1.8.0_111\jre
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: JVM Version: 1.8.0_111-b14
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: JVM Vendor: Oracle Corporation
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: CATALINA_BASE: C:\Users\dzhao\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: CATALINA_HOME: C:\Users\dzhao\Downloads\apache-tomcat-8.0.47
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dcatalina.base=C:\Users\dzhao\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dcatalina.home=C:\Users\dzhao\Downloads\apache-tomcat-8.0.47
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dwtp.deploy=C:\Users\dzhao\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Djava.endorsed.dirs=C:\Users\dzhao\Downloads\apache-tomcat-8.0.47\endorsed
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.VersionLoggerListener log
INFO: Command line argument: -Dfile.encoding=Cp1252
Oct 06, 2017 11:31:22 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.8.0_111\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_131/bin/server;C:/Program Files/Java/jre1.8.0_131/bin;C:/Program Files/Java/jre1.8.0_131/lib/amd64;C:\Program Files (x86)\GnuWin32\bin\;C:\Program Files (x86)\RBTools\bin;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Microsoft Online Services;C:\Program Files (x86)\Common Files\Microsoft Shared\Microsoft Online Services;C:\Program Files (x86)\IBM\RationalSDLC\common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\IBM\RationalSDLC\ClearCase\bin;C:\Program Files (x86)\IBM\gsk8\lib;C:\Program Files (x86)\IBM\gsk8\bin;C:\Program Files (x86)\IBM\RationalSDLC\ClearCase\RemoteClient\cteapis;C:\Program Files (x86)\Common Files\Check Point\UIFramework 3.0\Bin\;C:\Program Files (x86)\CheckPoint\Endpoint Security\Endpoint Common\bin;C:\Program Files (x86)\Sennheiser\SoftphoneSDK\;C:\Users\dzhao\Java_Softwares\eclipse;;.
Oct 06, 2017 11:31:22 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-nio-8080"]
Oct 06, 2017 11:31:22 AM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Oct 06, 2017 11:31:22 AM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-nio-8009"]
Oct 06, 2017 11:31:22 AM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFO: Using a shared selector for servlet write/read
Oct 06, 2017 11:31:22 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1209 ms
Oct 06, 2017 11:31:22 AM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Oct 06, 2017 11:31:22 AM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.47
Oct 06, 2017 11:31:25 AM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Oct 06, 2017 11:31:25 AM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Oct 06, 2017 11:31:25 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring FrameworkServlet 'springrest'
Oct 06, 2017 11:31:25 AM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'springrest': initialization started
Oct 06, 2017 11:31:25 AM org.springframework.web.context.support.XmlWebApplicationContext prepareRefresh
INFO: Refreshing WebApplicationContext for namespace 'springrest-servlet': startup date [Fri Oct 06 11:31:25 EDT 2017]; root of context hierarchy
Oct 06, 2017 11:31:25 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from ServletContext resource [/WEB-INF/springrest-servlet.xml]
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/country/{id}],methods=[GET],produces=[application/json]}" onto public org.arpit.java2blog.bean.Country org.arpit.java2blog.controller.CountryController.getCountryById(int)
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/countries],methods=[POST],produces=[application/json]}" onto public org.arpit.java2blog.bean.Country org.arpit.java2blog.controller.CountryController.addCountry(org.arpit.java2blog.bean.Country)
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/countries],methods=[PUT],produces=[application/json]}" onto public org.arpit.java2blog.bean.Country org.arpit.java2blog.controller.CountryController.updateCountry(org.arpit.java2blog.bean.Country)
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/country/{id}],methods=[DELETE],produces=[application/json]}" onto public void org.arpit.java2blog.controller.CountryController.deleteCountry(int)
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping register
INFO: Mapped "{[/countries],methods=[GET],produces=[application/json]}" onto public java.util.List org.arpit.java2blog.controller.CountryController.getCountries()
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: WebApplicationContext for namespace 'springrest-servlet': startup date [Fri Oct 06 11:31:25 EDT 2017]; root of context hierarchy
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: WebApplicationContext for namespace 'springrest-servlet': startup date [Fri Oct 06 11:31:25 EDT 2017]; root of context hierarchy
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.handler.SimpleUrlHandlerMapping registerHandler
INFO: Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
Oct 06, 2017 11:31:27 AM org.springframework.web.servlet.DispatcherServlet initServletBean
INFO: FrameworkServlet 'springrest': initialization completed in 2531 ms
Oct 06, 2017 11:31:27 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Oct 06, 2017 11:31:27 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Oct 06, 2017 11:31:27 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5321 ms
Это мой pom.xml:
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.arpit.java2blog</groupId>
<artifactId>AngularjsSpringRestExample</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>AngularjsSpringRestExample Maven Webapp</name>
<url>https://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
<build>
<finalName>AngularjsSpringRestExample</finalName>
</build>
</project>
сервлет.xml
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xmlns:mvc="https://www.springframework.org/schema/mvc" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd https://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context-3.0.xsd https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="org.arpit.java2blog.controller" />
<mvc:default-servlet-handler/>
</beans>
веб.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"https://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springrest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springrest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
класс контроллера:
package org.arpit.java2blog.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.arpit.java2blog.bean.Country;
import org.arpit.java2blog.service.CountryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CountryController {
@Autowired
private HttpServletRequest request;
CountryService countryService = new CountryService();
@RequestMapping(value = "/countries", method = RequestMethod.GET, headers = "Accept=application/json")
public List getCountries() {
List listOfCountries = countryService.getAllCountries();
return listOfCountries;
}
@RequestMapping(value = "/country/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
public Country getCountryById(@PathVariable int id) {
return countryService.getCountry(id);
}
@RequestMapping(value = "/countries", method = RequestMethod.POST, headers = "Accept=application/json")
public Country addCountry(@RequestBody Country country) {
return countryService.addCountry(country);
}
@RequestMapping(value = "/countries", method = RequestMethod.PUT, headers = "Accept=application/json")
public Country updateCountry(@RequestBody Country country) {
return countryService.updateCountry(country);
}
@RequestMapping(value = "/country/{id}", method = RequestMethod.DELETE, headers = "Accept=application/json")
public void deleteCountry(@PathVariable("id") int id) {
countryService.deleteCountry(id);
}
}
класс бобов:
package org.arpit.java2blog.bean;
public class Country{
int id;
String countryName;
long population;
public Country() {
super();
}
public Country(int i, String countryName,long population) {
super();
this.id = i;
this.countryName = countryName;
this.population=population;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
}
класс обслуживания:
package org.arpit.java2blog.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.arpit.java2blog.bean.Country;
/*
* It is just a helper class which should be replaced by database implementation.
* It is not very well written class, it is just used for demonstration.
*/
public class CountryService {
static HashMap<Integer,Country> countryIdMap=getCountryIdMap();
public CountryService() {
super();
if(countryIdMap==null)
{
countryIdMap=new HashMap<Integer,Country>();
// Creating some objects of Country while initializing
Country indiaCountry=new Country(1, "India",10000);
Country chinaCountry=new Country(4, "China",20000);
Country nepalCountry=new Country(3, "Nepal",8000);
Country bhutanCountry=new Country(2, "Bhutan",7000);
countryIdMap.put(1,indiaCountry);
countryIdMap.put(4,chinaCountry);
countryIdMap.put(3,nepalCountry);
countryIdMap.put(2,bhutanCountry);
}
}
public List getAllCountries()
{
List countries = new ArrayList(countryIdMap.values());
return countries;
}
public Country getCountry(int id)
{
Country country= countryIdMap.get(id);
return country;
}
public Country addCountry(Country country)
{
country.setId(getMaxId()+1);
countryIdMap.put(country.getId(), country);
return country;
}
public Country updateCountry(Country country)
{
if(country.getId()<=0)
return null;
countryIdMap.put(country.getId(), country);
return country;
}
public void deleteCountry(int id)
{
countryIdMap.remove(id);
}
public static HashMap<Integer, Country> getCountryIdMap() {
return countryIdMap;
}
// Utility method to get max id
public static int getMaxId()
{ int max=0;
for (int id:countryIdMap.keySet()) {
if(max<=id)
max=id;
}
return max;
}
}
HTML:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<title>AngularJS $http Rest example</title>
<script type="text/javascript">
var app = angular.module("CountryManagement", []);
//Controller Part
app.controller("CountryController", function($scope, $http) {
$scope.countries = [];
$scope.countryForm = {
id : -1,
countryName : "",
population : ""
};
//Now load the data from server
_refreshCountryData();
//HTTP POST/PUT methods for add/edit country
// with the help of id, we are going to find out whether it is put or post operation
$scope.submitCountry = function() {
var method = "";
var url = "";
if ($scope.countryForm.id == -1) {
//Id is absent in form data, it is create new country operation
method = "POST";
url = '/AngularjsSpringRestExample/countries';
} else {
//Id is present in form data, it is edit country operation
method = "PUT";
url = '/AngularjsSpringRestExample/countries';
}
$http({
method : method,
url : url,
data : angular.toJson($scope.countryForm),
headers : {
'Content-Type' : 'application/json'
}
}).then( _success, _error );
};
//HTTP DELETE- delete country by Id
$scope.deleteCountry = function(country) {
$http({
method : 'DELETE',
url : '/AngularjsSpringRestExample/country/' + country.id
}).then(_success, _error);
};
// In case of edit, populate form fields and assign form.id with country id
$scope.editCountry = function(country) {
$scope.countryForm.countryName = country.countryName;
$scope.countryForm.population = country.population;
$scope.countryForm.id = country.id;
};
/* Private Methods */
//HTTP GET- get all countries collection
function _refreshCountryData() {
$http({
method : 'GET',
url : 'https://localhost:8080/AngularjsSpringRestExample/countries'
}).then(function successCallback(response) {
$scope.countries = response.data;
}, function errorCallback(response) {
console.log(response.statusText);
});
}
function _success(response) {
_refreshCountryData();
_clearFormData()
}
function _error(response) {
console.log(response.statusText);
}
//Clear the form
function _clearFormData() {
$scope.countryForm.id = -1;
$scope.countryForm.countryName = "";
$scope.countryForm.population = "";
};
});
</script>
<style>
.blue-button{
background: #25A6E1;
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#25A6E1',endColorstr='#188BC0',GradientType=0);
padding:3px 5px;
color:#fff;
font-family:'Helvetica Neue',sans-serif;
font-size:12px;
border-radius:2px;
-moz-border-radius:2px;
-webkit-border-radius:4px;
border:1px solid #1A87B9
}
.red-button{
background: #CD5C5C;
padding:3px 5px;
color:#fff;
font-family:'Helvetica Neue',sans-serif;
font-size:12px;
border-radius:2px;
-moz-border-radius:2px;
-webkit-border-radius:4px;
border:1px solid #CD5C5C
}
table {
font-family: "Helvetica Neue", Helvetica, sans-serif;
width: 50%;
}
caption {
text-align: left;
color: silver;
font-weight: bold;
text-transform: uppercase;
padding: 5px;
}
th {
background: SteelBlue;
color: white;
}
tbody tr:nth-child(even) {
background: WhiteSmoke;
}
tbody tr td:nth-child(2) {
text-align:center;
}
tbody tr td:nth-child(3),
tbody tr td:nth-child(4) {
text-align: center;
font-family: monospace;
}
tfoot {
background: SeaGreen;
color: white;
text-align: right;
}
tfoot tr th:last-child {
font-family: monospace;
}
td,th{
border: 1px solid gray;
width: 25%;
text-align: left;
padding: 5px 10px;
}
</style>
<head>
<body ng-app="CountryManagement" ng-controller="CountryController">
<h1>
AngularJS Restful web services example using $http
</h1>
<form ng-submit="submitCountry()">
<table>
<tr>
<th colspan="2">Add/Edit country</th>
</tr>
<tr>
<td>Country</td>
<td><input type="text" ng-model="countryForm.countryName" /></td>
</tr>
<tr>
<td>Population</td>
<td><input type="text" ng-model="countryForm.population" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Submit" class="blue-button" /></td>
</tr>
</table>
</form>
<table>
<tr>
<th>CountryName</th>
<th>Population</th>
<th>Operations</th>
</tr>
<tr ng-repeat="country in countries">
<td> {{ country.countryName }}</td>
<td >{{ country.population }}</td>
<td><a ng-click="editCountry(country)" class="blue-button">Edit</a> | <a ng-click="deleteCountry(country)" class="red-button">Delete</a></td>
</tr>
</table>
</body>
</html>