are there any security modules in spring boot without spring security - java

I'm using spring boot version(2.0.1), and I have a problem with security, so when I try to make a request with ajax like this :
$.ajax({
url : "http://localhost:8080/utilisateurs/addUser",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type : "POST",
data : user,
dataType : "application/json"
}
i'm getting an HTTP error 403 , i know the meaning of this error ( the user can log in the server but don't have the right permission ) but the problem is i'm not using any module of security this is my dependancy pom.xml file :
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-hal-browser</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
so who can block the request, is there any internal module in spring boot how can enable the security,
see my previous post
thank you in advance.

the answer is to manage the CORS on the server side with adding #CrossOrigin annotation to the web service, the web service become like this :
package com.sid.webService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
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.sid.dao.entity.Utilisateur;
import com.sid.metier.IMetierUtilisateur;
#Component
#RestController
#RequestMapping("/utilisateurs")
public class webServiceUtilisateur {
#Autowired
private IMetierUtilisateur mr;
#CrossOrigin
#RequestMapping(value="/addUser",method=RequestMethod.POST)
public boolean addUser(#RequestBody Utilisateur u)
{
try
{
mr.ajouterUtilisateur(u);
return true;
}
catch(Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
}
and if you want more customization, add all the domains you are going to be accessing your spring backend from, and make them in the attribute origins like this :
#CrossOrigin(origins="http://localhost:8080/utilisateurs/")
#RequestMapping(value="/addUser",method=RequestMethod.POST)
public boolean addUser(#RequestBody Utilisateur u)
{
try
{
mr.ajouterUtilisateur(u);
return true;
}
catch(Exception e)
{
System.out.println(e.getMessage());
return false;
}
}
}

Related

<Spring Security> bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' cannot be found

Hi I am learning about Spring Security and was trying to create a simple OAuth2 client and resource server based on the guidelines at https://dzone.com/articles/implement-oauth-20-easily-with-spring-boot-and-spr
I came into an issue where the compiler keeps saying that it cannot find a bean for "ClientRegistrationRepository". I did some digging on the web, which says that if the Spring client configurations are configured correctly, it should work. Someone having similar issues said the problem may be caused by indetation issue in the properties file, but I am not seeing such case.
May I seek for your help to see if there is anything configured incorrectly, thanks.
Console output
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method webClient in com.somecompany.configuration.WebClientConfig required a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' in your configuration.
OAuth2 client main class
package com.somecompany;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Oauth2DemoClientApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2DemoClientApplication.class, args);
}
}
OAuth2 client controller
package com.somecompany.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
#RestController
#RequestMapping("/api/client")
public class Oauth2DemoClientController {
#Autowired
private WebClient webClient;
#Value("${resourceServer.url}")
private String resourceServerUrl;
#Value("${resourceServer.helloPath}")
private String resourceServerHelloPath;
#GetMapping("/")
public String home(#AuthenticationPrincipal OidcUser user) {
return "Welcome " + user.getFullName();
}
#GetMapping("/hello")
public String sayHello() {
return webClient.get().uri(resourceServerUrl + resourceServerHelloPath).retrieve().bodyToMono(String.class)
.block();
}
}
OAuth2 client configuration
package com.somecompany.configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
#Configuration
public class WebClientConfig {
#Value("${defaultClientApplication}")
private String defaultClientApplication;
#Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2 = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, authorizedClients);
oauth2.setDefaultOAuth2AuthorizedClient(true);
oauth2.setDefaultClientRegistrationId(defaultClientApplication);
return WebClient.builder().apply(oauth2.oauth2Configuration()).build();
}
}
OAuth2 client application.yml
logging.level.root: "debug"
defaultClientApplication: "okta"
spring:
security:
oauth2:
client:
provider:
okta:
issuer-uri: "https://dev-27548664.okta.com/oauth2/default"
registration:
okta:
client-id: {client ID}
client-secret: {client secret}
resourceServer:
url: "http://localhost:8081"
helloPath: "/api/resource/hello"
OAuth2 client pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.somecompany</groupId>
<artifactId>oauth2-demo-client</artifactId>
<version>1.0.0</version>
<name>oauth2-demo-client</name>
<description>oauth2-demo-client</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Issue is with your application.yml config indentation. security should be child of spring :
spring:
security:
oauth2:
Update:
YML properties are case sensitive. Try to change resourceServer to resourceserver
I'd suggest using the Okta Spring Boot starter. It shortens the spring.security.oauth2.* properties to be more intuitive.
okta.oauth2.issuer=<your-issuer>
okta.oauth2.client-id=<your-client-id>
okta.oauth2.client-secret=<your-client-secret>
If you want to use Spring Security, I'd recommend the following dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
Then, configure it as follows:
spring:
security:
oauth2:
client:
provider:
okta:
issuer-uri: <your-issuer>
registration:
okta:
client-id: <your-client-id>
client-secret: <your-client-secret>
scope: openid,profile,email

Spring beans are not initializing in Spring REST

My Spring beans are not getting initialized in Spring Java Config which I am using to create a sample Spring REST Application(As No Web.xml is required I have deleted it) . And also getting 404 while calling the REST endpoint /dest/types.
Can anyone please help. Project Structure
Pom.xml :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.travel</groupId>
<artifactId>patcyyRestApp</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>patcyyRestApp Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<springframework.version>5.0.9.RELEASE</springframework.version>
<jackson.library>2.9.6</jackson.library>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<hibernate.core.version>5.3.6.Final</hibernate.core.version>
<javax.servlet.api.version>3.1.0</javax.servlet.api.version>
<lombok.version>1.18.12</lombok.version>
<apache.commons.version>3.9</apache.commons.version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet.api.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.library}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.core.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${apache.commons.version}</version>
</dependency>
</dependencies>
<build>
<finalName>patcyyRestApp</finalName>
</build>
</project>
Dispatch Initializer :
package com.patcyy.rest.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class PatcyyDispatcherServletInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
System.out.println("Inside getServletConfigClasses");
return new Class[] { PatcyyConfig.class };
}
#Override
protected String[] getServletMappings() {
System.out.println("Inside mapping");
return new String[] { "/patcyy" };
}
}
Config :
package com.patcyy.rest.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#EnableWebMvc
#ComponentScan("com.patcyy.rest")
public class PatcyyConfig {
}
Controller :
package com.patcyy.rest.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.patcyy.rest.response.DestinationTypes;
import com.patcyy.rest.service.IDestinationService;
#RestController
#RequestMapping(path = "/dest", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces =
MediaType.APPLICATION_JSON_UTF8_VALUE)
public class DestinationController extends BaseController {
private final IDestinationService iDestinationService;
/**
* #param iDestinationService
*/
public DestinationController(#Autowired IDestinationService iDestinationService) {
super();
this.iDestinationService = iDestinationService;
}
#GetMapping("/types")
public ResponseEntity<List<DestinationTypes>> getDestinationTypes() {
List<DestinationTypes> destTypes = iDestinationService.getDestinationTypes();
return new ResponseEntity<List<DestinationTypes>>(destTypes, HttpStatus.OK);
}
}
I had to do two modifications to resolve the issue.
As i am using Java Config only, I had deleted the Web.xml. So i had to make changes in server.xml for Tomcat as :
<Context path="/patcyyRestApp" reloadable="true" docBase="D:\battleGround\patcyyRestApp\target\patcyyRestApp"/></Host>
I had to update the servlet mapping in the Dispatcher Intializer as :
return new String[] { "/patcyy/*" };
After making this two changes, It is working fine now.
Please take a look into this Tomcat without web xml
Please share console log for further investigation. As per my understanding after seeing above code , you can replace
"/patcyy" with only "/"
in getServletMappings() method.
your requested resource url will be like:
http://{hostname:port}/patcyyRestApp/dest/types
It's occurring due to invalid url servlet mapping.
i think the problem is in ComponentScan().
#ComponentScan annotation along with #Configuration annotation to specify the packages that we want to be scanned. #ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.
in your case you need to add basepackages="com.patcyy.rest"

Quarkus, Hibernate ORM and REST - RESTEASY008200: JSON Binding deserialization error:

I'm trying to create a project that uses Hibernate Panache and Rest, similar to the quickstart on https://github.com/quarkusio/quarkus-quickstarts/tree/master/hibernate-orm-panache-resteasy.
When I try to #Post an entity that extends PanacheEntity, as shown below, I get the following error:
javax.ws.rs.ProcessingException: RESTEASY008200: JSON Binding deserialization error: Can't create instance
Entity
#Entity
#Cacheable
class Trade extends PanacheEntity {
#Column(length = 40, unique = true)
String name;
}
Rest resource
import javax.enterprise.context.ApplicationScoped;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
#Path("/trades")
#ApplicationScoped
#Produces("application/json")
#Consumes("application/json")
public class TradeReporterResource {
#POST
#Transactional
public Response add(Trade trade) {
System.out.println("begin");
//t.closePrice = trade.closePrice;
System.out.println("persisting");
trade.persist();
System.out.println("persisted");
return Response.ok(trade).build();
}
}
Pom dependencies
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>${quarkus.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-openapi</artifactId>
</dependency>
</dependencies>
Problem appears to be with Penache
When I remove the extends PanacheEntity from the Trade entity, then at least I can POST successfully.
The problem turns out to be rather simple, all you need to do is make class Trade a public class.
It should be noted that this is not a Quarkus limitation, but a JSON-B limitation (which requires de-serialized classes to have a public or protected no-arg constructor - see section 3.7 of the JSON-B spec)

How to resolve this NetBeans error: "Make sure the project has been deployed successfully and the server is running"?

I am working on a Web Application using Maven, NetBeans 8.2 and jboss-eap 7.1 . I wrote the code below to test the Restful but when I run my code, I got this ERROR below :
Make sure the project has been deployed successfully and the server is running.
This is my code:
HelloWorld.java
package com.myws.webservice;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Path("/")
public class HelloWorld {
#Inject
HelloService helloService;
#GET
#Path("/xml")
#Produces({ "application/xml" })
public String getHelloWorldXML() {
return "<xml><result>" + helloService.createHelloMessage("World") + "</result></xml>";
}
}
HelloService.java
package com.myws.webservice;
public class HelloService {
String createHelloMessage(String name) {
return "Hello " + name + "!";
}
}
Dependencies in pom.xml
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.enterprise/cdi-api -->
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.annotation/jboss-annotations-api_1.2_spec -->
<dependency>
<groupId>org.jboss.spec.javax.annotation</groupId>
<artifactId>jboss-annotations-api_1.2_spec</artifactId>
<version>1.0.2.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.spec.javax.ws.rs/jboss-jaxrs-api_2.0_spec -->
<dependency>
<groupId>org.jboss.spec.javax.ws.rs</groupId>
<artifactId>jboss-jaxrs-api_2.0_spec</artifactId>
<version>1.0.1.Final</version>
</dependency>
</dependencies>
Any help understanding how to proceed with this error from here? Thanks!

Spring boot annotation confusion

I am creating a spring boot application based on an assignment in an online MOOC. The course is over and I am just trying the assignment on my own.
THis is my pom.xml file:
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.samples.service.service</groupId>
<artifactId>VideoManagerServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- Generic properties -->
<java.version>1.6</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Web -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- Spring -->
<spring-framework.version>3.2.3.RELEASE</spring-framework.version>
<!-- Hibernate / JPA -->
<hibernate.version>4.2.1.Final</hibernate.version>
<!-- Logging -->
<logback.version>1.0.13</logback.version>
<slf4j.version>1.7.5</slf4j.version>
<!-- Test -->
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<!-- Other Web dependencies -->
<!-- Spring and Transactions -->
<!-- Logging with SLF4J & LogBack -->
<!-- Hibernate -->
<!-- Test Artifacts -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
THis is my controller:
import java.util.ArrayList;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.hakeem.videoserver.model.Video;
import com.hakeem.videoserver.service.VideoService;
#RestController
#RequestMapping(value="/api",consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)
public class VideoController {
#Autowired
VideoService videoService;
#RequestMapping(value="/add",method=RequestMethod.POST)
public void addVideo(#RequestBody Video video){
videoService.addVideo(video);
}
#RequestMapping(value="/all",method=RequestMethod.GET)
public #ResponseBody ArrayList<Video> getAllVideos(HttpServletResponse response){
ArrayList<Video> videos;
videos = videoService.getAllVideos();
if(videos.size() == 0){
response.setStatus(HttpStatus.NO_CONTENT.value());
}
return videos;
}
#RequestMapping(value="/delete",method=RequestMethod.DELETE)
public void deleteVideo(#RequestBody Video video){
videoService.deleteVideo(video);
}
#RequestMapping(value="/find/{id}")
public #ResponseBody Video findVideo(#PathVariable int id, HttpServletResponse response){
return videoService.findVideo(id);
}
#RequestMapping(value="/testing",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody int testEndPoint(HttpServletResponse response){
return 10;
}
}
The problem is my addVideo endpoint only works when I annotate with #RestController but not when I annotate with #Controller.
However my testEndpoint method works when I annotate with #RestController and #Controller
However if I add #ResponseBody to the Class or the addVideo method then it works.
Using the Postmat plugin on Chrome, when I send the following Post Request:
http://localhost:8080/api/add
With this body for a video:
{
"id":1,
"title":"test",
"contentType":"test1",
"dataUrl":"testurl",
"starRating":"5",
"duration":7
}
I get this message in Postman:
{ "timestamp": 1440349612613,
"status": 405,
"error": "Method Not Allowed",
"exception":"org.springframework.web.HttpRequestMethodNotSupportedException", "message": "Request method 'POST' not supported", "path": "/api/add"
}
And this message in my eclipse console:
WARN PageNotFound - Request method 'POST' not supported
But the video is add and can be retrieved without any errors if I had #ResponseBody to the class or the method return type.
Therefore the main question is:
Why do I need to add #ResponseBody if the addVideo is not returning anything.
There were two questions asked here:
Why #RestController works, but #Controller does not?
If you check the documentation, you will see that RestController is
A convenience annotation that is itself annotated with #Controller
and #ResponseBody.
Why do you need to add #ResponseBody if the return type is void?
The reason for this is that even if there is no actual value you want to return, there will be a response sent to the client (at least an HTTP OK). For this reason you need to use one of these:
#ResponseBody
#ResponseStatus(value = HttpStatus.OK)

Categories