I am trying to load js files in my spring boot application, but when I try to load "/resources/static/js/jsfile.js" using the url http://localhost:8080/js/jsfile.js I am getting a 404 not found error.
I need to prevent this controller from getting called when I try to load something in src/main/resources/static/
#GetMapping("/{username}/{slug}")
public String single(#PathVariable("username") String username, #PathVariable("slug") String slug, Model model) {
model.addAttribute("user", postService.getSinglePost(slug, username));
return "/post/single";
}
After reading other solutions I tried creating this but I'm still getting 404 errors.
#Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
registry
.addResourceHandler("/css/**")
.addResourceLocations("/css/");
registry
.addResourceHandler("/img/**")
.addResourceLocations("/img/");
registry
.addResourceHandler("/js/**")
.addResourceLocations("/js/");
}
}
Related
I'm actually trying to access the method at that endpoint but I keep getting the classic CORS error
"Access to XMLHttpRequest at 'http://localhost:8080/rpc-measurements' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
#JsonRpcService("rpc-measurements")
public interface JsonRpcAPI {
public List<Measurements> getMeasurementsByDays(String username, int days);
public Float getAvgEnergyConsumption();
public String getUsername(String username);
}
The implementation:
#Service
#AutoJsonRpcServiceImpl
public class JsonRpcAPIimpl implements JsonRpcAPI {
#Autowired
private MeasurementsRepository measurementsRepository;
#Autowired
private DeviceRepository deviceRepository;
#Autowired
private PersonRepository personRepository;
#Override
public List<Measurements> getMeasurementsByDays(String username, int days) {
Person person = personRepository.findByName(username);
List<Device> devices = deviceRepository.findByPersonId(person.getId());
List<Measurements> measurements = new ArrayList<>();
devices.forEach(x -> {
measurements.addAll(measurementsRepository.getEnergyConsumptionForDays(UuidAdapter.getBytesFromUUID(x.getId()), days));
});
return measurements;
}
#Override
public Float getAvgEnergyConsumption() {
return 0.0f;
}
#Override
public String getUsername(String username) {
return username;
}
}
The security configuration file:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Resource(name = "userService")
private CustomUserService userService;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.anyRequest().permitAll()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
/*http.csrf().disable().authorizeRequests()
.anyRequest().permitAll();*/
}
#Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
#Autowired
private UnauthorizedEntryPoint unauthorizedEntryPoint;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
}
And finally the react js function that calls the API:
function handleValueSelect(event) {
axios.post(REST_API_URL + '/rpc-measurements', {
id: "1",
jsonrpc: "2.0",
method:"getAvgEnergyConsumption",
params:[]
},{
headers: {
Authorization: "Bearer " + localStorage.getItem('userToken')
}
}).then(res => {
setDataP(res.data.map((data) => ({
time: ((data.time.split('T')[1])
.split('+')[0])
.split('.')[0],
value: data.value
})));
});
};
I have been wasting half a day trying to find some solutions, most of the problems related to the CORS policy error that I found on the internet were solved by either adding the #CrossOrigin annotation to a controller or by adding http.cors() in the security configuration file, the thing is that I am not trying to access an endpoint from a controller I am trying to access an endpoint from a json rpc service in order to use a method from there and I have no idea if I have to set up cross origin for that particular path in a different way compared to a controller (where you just use the annotation, and yes I already tried adding it to the service).
The weirdest thing is that I tried accessing the URL in postman with exactly the same body as in the axios request and it worked, but when I tried in the web client the CORS error kept popping up. I even tried creating a Rest Controller and using JsonRpcRestClient to invoke the method but it didn't work, it freezes my spring app, I don't even get an error or an exception in the console, it just stops responding.
So I wanted to ask if there's someone who's been in a similar situation or has some ideas on how to deal with the CORS policy error taking into account that I am trying to access an end point from a Service and not a controller.
I have faced the same issue with react and spring.
In this case, browser is blocking your request.
put the reactjs build file inside template folder and run spring boot sends index.html then reactjs start works and cros error not come but it requires restController for all other requests.
servlet not doing redirect, used Spring Boot 2.4.1. Code and comments below.
Class servlet
code
#WebServlet(name = "estore",
urlPatterns = {"/"},
loadOnStartup = 1)
public class EstoreServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
IOException{
// Here logic and after need redirect
response.sendRedirect("/index.html");
}
}
Information from request
code
Session - org.apache.catalina.session.StandardSessionFacade#2e555cdd
Servlet path - /
Server name - localhost
Local name - 0:0:0:0:0:0:0:1
Local addr - 0:0:0:0:0:0:0:1
Get Remote user - null
Get method - GET
Get protocol - HTTP/1.1
Get content type - null
Get server port - 8080
Get sheme - http
Get Request URI - /
Get Context Path -
Spring MVC configuration file
code
#Configuration
#ServletComponentScan(basePackages = "internet_store.web_ui.servlet")
#EnableWebMvc
public class MvcConfiguration implements WebMvcConfigurer {
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver resourceViewResolver = new SpringResourceTemplateResolver();
resourceViewResolver.setPrefix("classpath:/templates/internet_store/");
resourceViewResolver.setSuffix(".html");
resourceViewResolver.setTemplateMode(TemplateMode.HTML);
resourceViewResolver.setCharacterEncoding("UTF-8");
resourceViewResolver.setCheckExistence(false);
return resourceViewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/", "classpath:/templates/internet_store/")
.setCachePeriod(320000)
.resourceChain(true)
.addResolver(new PathResourceResolver());
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable("estore");
}
}
Project structure
Resources
This code return error in browser ERR_TOO_MANY_REDIRECTS. If in controller set return "redirect:/foo" then redirect not doing too. Example below.
code
#GetMapping(value = "/back_client")
public String backButtonClientFormPressed() {
return "service/service";
}
index.html have controller with method
code
#GetMapping(value = "/index")
public String index(ModelMap modelMap) {
updatePage();
Path resourceDirectory = Paths.get("resources");
modelMap.addAttribute("error", "");
refreshData(modelMap);
return "index";
}
Change service/service to redirect:/index going to error ERR_TOO_MANY_REDIRECTS. Maybe problems with resources path? Thank You for You attention.
[SOLVED]
Need delete response.sendRedirect("/index.html"); from servlet class and add
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
Assume that Project is our POJO class. Following function provides to delete a row from database. It is successfully working with POSTMAN requests.
#RestController
#RequestMapping(value = "/project")
#CrossOrigin
public class ProjectController {
private final ProjectServiceImpl projectServiceImpl;
------------
#DeleteMapping
#RequestMapping("/delete/{id}")
public ResponseEntity<Boolean> deleteProject(#PathVariable Long id) {
boolean result = projectServiceImpl.delete(id);
return ResponseEntity.ok(result);
}
------------
}
But requests from Angular project are rejecting with 403 message. And following message is appearing in console screen.
After some searches. I learned, the application have to answer pre-flight requests with 200. To provide this, following function was added to controller.
#GetMapping
#RequestMapping("/delete/{id:[0-9]+}")
public ResponseEntity.BodyBuilder retreive(#PathVariable Long id) {
return ResponseEntity.ok();
}
I used regex for request mapping because without it Spring Framework throws /project/delete/{id} already mapped with another function. Angular get its 200OK for pre-flight request with this way. But the application response is 406 for delete operation. Angular is sending http://localhost:8080/project/delete/2 url to the application. If I send same link without have a function for CORS. Row has id with 2 will delete successfully. Am I missing something?
Sources:
Why Angular sending OPTIONS message before DELETE
How to add CORS support to Spring Boot application
To implement server side proxy: proxy.conf.json
{
"/project/**": {
"target": "http://localhost:8080",
"secure": false
}
}
modified section in angular.json
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "issue-management:build",
"proxyConfig": "proxy.conf.json"
},
and Angular project started with ng serve --proxy-config proxy.conf.json but result didn't change. Plus, suggestions in this article applied, again result didn't change.
Your applications are running on two different ports, that causing the CORS issue.
Add the proxy(file proxy.conf.json) in your Angular application.
{
"/project/**": {
"target": "http://localhost:8080",
"secure": false
}
}
and run this ng serve --proxy-config proxy.conf.json
Refference Angular doc
Update:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*")
.allowedOrigins("http://localhost:4200");
}
};
}
worked, For some reason Angular proxy is not working
If you are using spring security use the following:
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors(withDefaults())
...
}
#Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
See spring documentation: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#cors
Global configuration:
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Value("${cors.origins.urls}")
public String allowedOrigins;
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedOrigins(allowedOrigins.split(","));
}
}
I have a vuejs + spring boot app. All was working fine, but suddenly got this issue - requests to files in /js/, /css/, /img/ are returning the index.html content despite having a resource mapping pointing to classpath:/static.
Can't trance the original change which lead to the appearance of this problem. front-end works fine by itself (tried deploying to surge & zeit now), so i suppose the problem is that spring boot ignores the resource mapping.
spring boot v2.1.2
WebMvcConfig:
#Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
String baseApiPath = "/api";
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/**/*.css", "/**/*.html", "/**/*.js", "/**/*.png", "/**/*.ttf")
.setCachePeriod(0)
.addResourceLocations("classpath:/static/");
registry.addResourceHandler("/")
.setCachePeriod(0)
.addResourceLocations("classpath:/static/index.html")
.resourceChain(true)
.addResolver(new PathResourceResolver() {
#Override
protected Resource getResource(String resourcePath, Resource location) throws IOException {
if (resourcePath.startsWith(baseApiPath) || resourcePath.startsWith(baseApiPath.substring(1))) {
return null;
}
return location.exists() && location.isReadable() ? location : null;
}
});
}
}
in index.html links like this <script src=/js/chunk-vendors.b7114b0e.js></script><script src=/js/app.5c7ddca5.js></script> returning the index.html itself.
Following code below is Spring Boot Serving Images Configuration.
#Configuration
public class StaticResourceConfiguration extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
super.addResourceHandlers(registry);
/*registry.addResourceHandler("/images/**").addResourceLocations("file:/home/test/images");*/
registry.addResourceHandler("/images/**").addResourceLocations("file:///C:/test/images/");
}
#Override
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Till Yesterday, It was serving properly.But all of sudden its serving like this.
If I try to access same image using file path url its working fine eg
file:///C:/test/images/profile/5880b70d91286e0318863818/APM1243//originalImage_k3kf6nxil1en8yi_.jpeg
Please help me?
Its not because of backend code(Java), image was not displaying properly. Its because of browser, when I do empty cache reload image is rendering properly.