I'm fairly new to all of this. This is the problem. I have a REST API using Spring Boot hooked up to MySQL. The URL to access my API is http://localhost/videogamereview/review/(id) . Whenever I access this URL I get my JSON object as expected.
I also have a separate angular project which connects to this API via its own routes. For instance: HTTP:localhost:8080/angular2/#!/ should make a call to the API, however I get a 404 response from the browser.
spring configuration file:
package com.init;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan(basePackages = "com")
@EnableTransactionManagement
public class MvcConfiguration extends WebMvcConfigurerAdapter {
private static final String DATABASE_DRIVER = "com.mysql.jdbc.Driver";
private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/videogamereviews?verifyServerCertificate=false&useSSL=true";
private static final String DATABASE_USERNAME = "root";
private static final String DATABASE_PASSWORD ="random";
private static final String HIBERNATE_DIALECT = "org.hibernate.dialect.MySQLDialect";
private static final String HIBERNATE_SHOW_SQL = "true";
private static final String ENTITYMANAGER_PACKAGES_TO_SCAN = "com.model";
private static final String HIBERNATE_HBM2DDL_AUTO = "create-drop";
// private static final String HIBERNATE_HBM2DDL_AUTO = "update";
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(DATABASE_DRIVER);
dataSource.setUrl(DATABASE_URL);
dataSource.setUsername(DATABASE_USERNAME);
dataSource.setPassword(DATABASE_PASSWORD);
return dataSource;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", HIBERNATE_DIALECT);
properties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
properties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
return properties;
}
@Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
@Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/css/**").addResourceLocations("/resources/");
}
}
my controller in spring: ReviewController.java
package com.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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;
import com.model.Review;
import com.service.ReviewService;
@RestController
@RequestMapping(value = "review")
@CrossOrigin(origins="http://localhost:8080")
public class ReviewController {
@Autowired
private ReviewService rs;
@RequestMapping(value="/",method = RequestMethod.GET)
public List<Review> getReviews() {
return rs.getReviews();
}
@RequestMapping(value = "{id}", method = RequestMethod.GET)
public Review showReviewWithId(@PathVariable long id) {
return rs.getReviewById(id);
}
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public String updateReviews(@PathVariable long id, @RequestBody Review review) {
rs.updateReview(id,review);
return "review updated";
}
@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
public String delete(@PathVariable long id) {
rs.deleteReview(id);
return "review deleted";
}
@RequestMapping(value="/",method = RequestMethod.POST)
public String postReview(@RequestBody Review review) {
rs.saveReview(review);
return "review created";
}
}
angular setup: app.js
'use strict';
var VideogameReviewsApp = angular.module('VideogameReviewsApp', ['ngRoute','ngResource']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/', { controller: ReviewCtrl, templateUrl: 'review.html' }).
otherwise({ redirectTo: '/' });
}]);
VideogameReviewsApp.factory('Review', function ($resource) {
return $resource('http://localhost/videogamereviews/review/:id.json', { id: '@id' },
{ update: { method: 'PUT' } });
});
var ReviewCtrl = function ($scope,Review) {
alert("haha");
$scope.reviews = Review.query();
};
In the browser headers section, I can see that the URL which is being accessed is http://localhost/videogamereviews/review.json . So why am I getting a 404
response? Thanks in advance! Ashley
According to ReviewController reviews should be accesible through http://localhost/review and a review with given id should be accessible through http://localhost/review/YOUR_REVIEW_ID
so you have to remove .json from end of request url.
If http://localhost/videogamereview/review/(id) returns an expected JSON, so use it in your Angular script. That mean removing .json
in uri when you want to retrieve a resource. http://localhost/videogamereview/review/(id) returns a JSON resource, but http://localhost/videogamereview/review/(id).json is not.
your url have colon (:) which is causing the issue. just paste your resource uri in browser(check in browser console about the response) or use postman. from your spring controller the GET Request should be as below:
also I am considering the localhost is mapped to localhost:{app server portno}. (ie localhost:8080) and context root is videogamereviews .
Apparently angular requested the resource at " http://localhost/videogamereviews/review "
However my api must be accessed at " http://localhost/videogamereviews/review / ".
So angulars default behavior is (from the documentation) "By default, trailing slashes will be stripped from the calculated URLs, which can pose problems with server backends that do not expect that behavior. This can be disabled by configuring the $resourceProvider like this:"
So in I app.js I needed to add the following:
app.config(['$resourceProvider', function($resourceProvider) {
// Don't strip trailing slashes from calculated URLs
$resourceProvider.defaults.stripTrailingSlashes = false;
}]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.