Swagger doesn't add new api controllers to rest (Spring boot) - spring-boot

Swagger doesn't recognize a new interface of rest api.
This are swagger configuration file.
package trn06.administracion.api.configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.extern.slf4j.Slf4j;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Slf4j
#EnableSwagger2
#Configuration
public class TRN06SwaggerConfiguration {
#Value("${custom.host}")
private String hostValue;
private ApiInfo _apiInfo(final String version) {
return new ApiInfoBuilder()
.title("Administrative events")
.termsOfServiceUrl("")
.version(version)
.contact(new Contact("",
"",
""))
.build();
}
private Docket _configureVersion(final String version) {
// Get environment from java environment variables
return new Docket(DocumentationType.SWAGGER_2)
.host(hostValue)
.groupName("Version_" + version)
.select()
.apis(RequestHandlerSelectors.basePackage("trn06.administracion.api.controller.rest"))
.paths(PathSelectors.ant("/v" + version + "/**"))
.build()
.useDefaultResponseMessages(false)
.apiInfo(_apiInfo(version));
}
#Bean
Docket configureV1_0() {
return _configureVersion("1.0");
}
}
All interfaces defined on package trn06.administracion.api.controller.rest are ok, in fact I have two other interfaces mapped ok, except this one:
package trn06.administracion.api.controller.rest;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import trn06.administracion.api.model.dto.TRN06ErrorDto;
import trn06.administracion.api.model.dto.TRN06EventsAuthorityDto;
import trn06.administracion.api.model.dto.TRN06ValidationErrorDto;
import java.util.List;
#Api(value = "authorities", description = "Event's authorities ", tags = "Authorities")
public interface TRN06EventsAuthorityApiController {
#ApiOperation(value = "List of authorities", nickname = "findAuthorities", response = TRN06EventsAuthorityDto.class, responseContainer = "List", tags = {"Authorities,"})
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Operation performed", response = TRN06EventsAuthorityDto.class, responseContainer = "List"),
#ApiResponse(code = 400, message = "Validation error", response = TRN06ValidationErrorDto.class),
#ApiResponse(code = 404, message = "Not found"),
#ApiResponse(code = 500, message = "Error", response = TRN06ErrorDto.class)})
#GetMapping(value = "/v1.0/authorities",
produces = "application/json")
List<TRN06EventsAuthorityDto> findAuthorities();
}
Looks like database entity it's ok, I try making an error and was detected correctly. Try changing RequestHandlerSelectors to any(), same results.
No idea and no clue of whats appening.
Kind regards

You need to create an implementation of this interface and add #RestController and #RequestMapping annotations in the implementation.
For example:
#RestController
#RequestMapping("/findAuthorities")
public class TRN06EventsAuthorityApiControllerImpl implements TRN06EventsAuthorityApiController {
#Override
public List<String> findAuthorities() {
return null;
}
}

In my case, was an annotation I forgot
public class TRN06EventsTypesApiControllerImpl
implements TRN06EventsTypesApiController {
....
After put anotation #RestController was fine
#RestController
public class TRN06EventsTypesApiControllerImpl
implements TRN06EventsTypesApiController {
....
Anyway, I take the note of #RequestMapping annotation.
Thanks #v-mokrecov and #mahesh-loya

Related

Spring Boot TestRestTemplate return null body

Havin a quite very simple test class followed by a video tut:
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class TestClassTest {
#LocalServerPort
private int port;
#Autowired
private TestRestTemplate testRestTemmplate;
#Test
public void test_one() {
String url = "http://localhost:" + port + "/v1/read";
UriComponents builder = UriComponentsBuilder.fromHttpUrl(url).build();
HttpHeaders headers = new HttpHeaders();
headers.set("accept", "application/json");
HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);
ResponseEntity<String> response = testRestTemmplate.exchange(builder.toString(), HttpMethod.GET, requestEntity, String.class);
System.out.println(response.getBody());
assertEquals(HttpStatus.OK, response.getStatusCode());
}
}
The underlying controller class for test looks like:
#RestController
public class TestController {
#RequestMapping(value = "/v1/read", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<String> data() {
return ResponseEntity.status(HttpStatus.OK).header("status", "completed").body("fertig!");
}
}
Some issues i wondering with:
Running the test will evaluate to green thats fine but if i change the url in the test it will be also OK
The body from response is null and
the header i set within the ResponseEntity is no part of the response from testResttemplate.
Where are my misunderstandings?
Edit: here are my imports:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
As seen this are only the "standard" import coming from spring dependencies. Nothing exotics.

Spring rest controller does not validate my DTO

I have this request and response:
#Data
public class TestRequestDto {
#Min(7)
private String name;
}
#Data
public class TestResponseDto {
private String response;
}
And I have a controller:
package com.example.validation.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
#Slf4j
#RestController
public class TetController {
#PostMapping("/test")
public TestResponseDto getTestResponseDto(#Valid #RequestBody TestRequestDto request){
log.info(request.getName());
TestResponseDto response = new TestResponseDto();
response.setResponse("response");
return response;
}
}
I send a post request({"name":"test"}) with an invalid name but it works. What am I doing wrong?
Starting with Boot 2.3, we also need to explicitly add the spring-boot-starter-validation dependency

SFTP File Download in Spring Boot

I created one spring boot app. I need to upload any file(doc,pdf,mp3 etc..) on sftp server. when user upload file my spring app can able to create url and save file details(on which server file is located, download url of file, who is the own of that file etc..) to h2 database.
and when user ask for file.. spring boot can able to fetch file details form database.. and display that file on browser. and user can also able to download that file. can any one help..enter image description here
Java Configuration
import com.example.springintegrationhttp.FilePrinter;
import org.springframework.context.annotation.Bean;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.InboundChannelAdapter;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.filters.AcceptOnceFileListFilter;
import org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter;
import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizer;
import org.springframework.integration.sftp.inbound.SftpInboundFileSynchronizingMessageSource;
import org.springframework.integration.sftp.outbound.SftpMessageHandler;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.stereotype.Component;
import java.io.File;
#org.springframework.context.annotation.Configuration
#Component
public class Configuration {
#Bean
public DefaultSftpSessionFactory sftpSessionFactory(){
DefaultSftpSessionFactory defaultSftpSessionFactory = new DefaultSftpSessionFactory();
defaultSftpSessionFactory.setHost("0.0.0.0");
defaultSftpSessionFactory.setPort(22);
defaultSftpSessionFactory.setUser("abhishek");
defaultSftpSessionFactory.setPassword("12345");
defaultSftpSessionFactory.setAllowUnknownKeys(true);
System.out.println("Value in SftpSession: " + defaultSftpSessionFactory);
return defaultSftpSessionFactory;
}
#Bean
#ServiceActivator(inputChannel = "tosftpChannel")
public MessageHandler handler(){
SftpMessageHandler messageHandler = new SftpMessageHandler(sftpSessionFactory());
messageHandler.setRemoteDirectoryExpression(new LiteralExpression("upload"));
messageHandler.setFileNameGenerator(new FileNameGenerator() {
#Override
public String generateFileName(Message<?> message) {
System.out.println(message.getHeaders().get("fileName"));
System.out.println(message.getPayload());
return message.getHeaders().get("fileName").toString();
}
});
return messageHandler;
}
#Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer(){
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory("upload");
System.out.println("M a gaya");
fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.txt"));
return fileSynchronizer;
}
#Bean
//#InboundChannelAdapter(channel = "sftpChannel", poller = #Poller(fixedDelay = "5000"))//,autoStartup = "false")
#InboundChannelAdapter(channel = "sftpChannel")//,autoStartup = "false")
public MessageSource<File> sftpMessageSource(){
System.out.println("Into sftpMessageSource()");
SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
source.setLocalDirectory(new File("target/foo"));
source.setAutoCreateLocalDirectory(true);
System.out.println("Flow");
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
source.setMaxFetchSize(1);
//sftpInboundFileSynchronizer();
return source;
}
/*OutBoundGateway*/
/* #Bean
#ServiceActivator(inputChannel = "sftpChannel",)
public MessageHandler handler(){
SftpOutboundGateway outboundGateway = new SftpOutboundGateway(sftpSessionFactory(),
"get","payload");
outboundGateway.setLocalDirectory(new File("target/gatewayhand"));
outboundGateway.setAutoCreateLocalDirectory(true);
return outboundGateway;
}*/
/*OutBoundGateway*/
#Bean
#ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler DownloadHandler(){
//return new SftpOutboundGateway(sftpSessionFactory(),"ls");
return message -> {
System.out.println("In Service Activator: " + message.getPayload());
File f = (File) message.getPayload();
FilePrinter f2 = new FilePrinter();
f2.print(f);
System.out.println(f.getName());
//sftpMessageSource();
//p.print(File file);
};
}
}
Gateway
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
#Component
#MessagingGateway
public interface UplaodGateway {
#Gateway(requestChannel = "tosftpChannel")
public void sendToSftp(#Header("fileName") String fileName, InputStream file);
/* #Gateway(requestChannel = "sftpChannel")
public void read(String fileName);*/
}
Controller
import com.example.springintegrationhttp.service.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.websocket.server.PathParam;
import java.io.IOException;
#RestController
//#RequiredArgsConstructor
public class uplaodController {
#Autowired
UploadService uploadService;
#PostMapping("/upload")
public ResponseEntity<String> upladFile(#RequestParam("file")MultipartFile file) throws IOException {
return uploadService.uplaodToServer(file);
}
#GetMapping("/read")
public String readf(#PathParam("fileName")String fileName){
uploadService.readFileFromServer(fileName);
return "I want to fetch that file which user want";
}
}
//}
Thank You

Spring Get Mapping isn't working

I'm using Angular 4 with Spring backend. And.... My post request working fine. But the get request don't work. Look the code:
Frontend Service:
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/toPromise';
import { Aluno } from '../models/aluno.model';
import {HttpClient} from "#angular/common/http";
import {Observable} from "rxjs/Observable";
#Injectable()
export class UserDataService {
private url = 'http://localhost:8080/getAluno';
constructor(private http: HttpClient){}
getAluno():Observable<Aluno>{
return this.http.get<Aluno>(this.url);
}
}
My spring backend provider:
import com.google.gson.Gson;
import com.ifmg.tcc.TADs.Aluno;
import com.ifmg.tcc.TADs.LoginObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
public class LoginProvider {
Gson gson = new Gson();
private boolean verify(LoginObject lo){
if(lo.getCode().equals("lucas") && lo.getPassword().equals("12345")){
return true;
}else{
return false;
}
}
#PostMapping(value = "login")
public ResponseEntity<?> verifyLogin(#RequestBody String login){
System.out.println("LOGIN REALIZADO");
LoginObject loginO = gson.fromJson(login, LoginObject.class);
if(verify(loginO)){
return new ResponseEntity<Boolean>(true,HttpStatus.OK);
}else{
return new ResponseEntity<Boolean>(false,HttpStatus.OK);
}
}
#GetMapping(value = "/getAluno")
public #ResponseBody ResponseEntity<?> getAluno() {
System.out.println("PEGANDO ALUNO");
Aluno aluno = new Aluno("0001","Lucas Alves de Faria","2018/1","10/12/1995",true,"luke#email.com","(37) 999597899","127.831.956-58","MG-19.319.265");
return new ResponseEntity<Aluno>(aluno, HttpStatus.OK);
}
}
The function verify login in my backend working fine(I'm call this function in other service). But the fontend don't call the other function (getAluno)
I'm not sure about what you mean when you say "But the fontend don't call the other function (getAluno)". You may look at your network calls and verify the calls.
In your front component which calls your service, you need to have a subscribe, something like this :
this.yourService.getAluno().subscribe(
(res: ResponseEntity) => {
this.aluno = res.json;
},
(res: ResponseEntity) => this.onError(res.json)
);
Hope it helps you.

Spring boot rest : Circular view path [error]: would dispatch back to the current handler URL [/error] again

My issue is I get 404 error when calling the spring boot application on localhost:8080/users
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import java.security.Principal;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.myproj.users.Greeting;
import com.myproj.users.PhysicalCharacteristicsRepository;
import com.myproj.users.UserRepository;
import com.myproj.users.UserResource;
#RestController
#RequestMapping("/users")
public class UserRestController {
private UserRepository userRepository;
private PhysicalCharacteristicsRepository characteristicsRepository;
#RequestMapping(value = "/greeting/", method = RequestMethod.GET)
public String greeting() throws UserPrincipalNotFoundException {
return "Greeting";
}
#RequestMapping(value = "/error/")
public String error() {
return "Error handling";
}
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody Greeting sayHello(#RequestParam(value = "name", required = false, defaultValue = "Stranger") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
#Autowired
UserRestController(UserRepository userRepository, PhysicalCharacteristicsRepository characteristicsRepository) {
this.userRepository = userRepository;
this.characteristicsRepository = characteristicsRepository;
}
}
package com.myproj.users.controller;
import java.nio.file.attribute.UserPrincipalNotFoundException;
import org.springframework.hateoas.VndErrors;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.weather.exceptions.UserNotFoundException;
#ControllerAdvice
class UserControllerAdvice {
#ResponseBody
#ExceptionHandler(UserNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userNotFoundExceptionHandler(UserNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
#ResponseBody
#ExceptionHandler(UserPrincipalNotFoundException.class)
#ResponseStatus(HttpStatus.NOT_FOUND)
VndErrors userPrincipalNotFoundException(UserPrincipalNotFoundException ex) {
return new VndErrors("error", ex.getMessage());
}
}
package com.myproj.users;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
I have tested the spring project in https://spring.io/guides/gs/actuator-service/ and it worked so I ignore what's going on.
I have defined a controller to manage errors. I have copied it from Spring Boot Remove Whitelabel Error Page
The new Application class is the following :
package com.test;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#Configuration
#ComponentScan(basePackages = "com.test")
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
public class Application {
static final Logger logger = LogManager.getLogger(Application.class.getName());
public static void main(String[] args) {
logger.debug("Entered the application");
SpringApplication.run(Application.class, args);
}
private Application() {
}
}
As you can see I have added a controller in ComponentScan as follows :
#ComponentScan(basePackages = "com.test")
#EnableJpaRepositories(basePackages = "com.test")
#EntityScan(basePackages = "com.test")
To test I used curl curl http://localhost:9002/eleves/Hammami/ and firefox.
Changing #Controller to #RestController solved my issue.
In my case I was using thymeleaf(MVC), after that I switched to pure backend.

Resources