Cannot using "response.setService/.setMesage/.setData" in java maven springboot project - java

I try to build API with springboot, when i make controller and using response.response.setService/.setMesage/.setData i get error "The method setService(String) is undefined for the type Response", please help me to solve this problem.
package com.example.restapi.controller;
import com.example.restapi.entity.Hardware;
import com.example.restapi.service.HardwareService;
import com.example.restapi.util.Response;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
#RestController
#RequestMapping(value = "hardware")
public class HardwareController {
#Autowired
HardwareService hardwareService;
private String serviceString = "Hardware";
ResponseEntity<Response> create (#RequestBody #Validated Hardware hardware)
{
String nameofCurrMethod = new Throwable()
.getStackTrace()[0]
.getMethodName();
Response response = new Response();
response.setService(this.getClass().getName() + nameofCurrMethod); <==This is error code
response.setMessage("Berhasil Membuat Data"); <==This is error code
response.setData(hardwareService.create(hardware)); <==This is error code
return ResponseEntity
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(response);
}
}

Related

Request method 'GET' not supported] error for method using #DeleteMapping

I'm getting a error like:
Request method 'GET' not supported for a method (deleteProductById)
using the #DeleteMapping annotation whenever I visit the URL mapped to said method (http://localhost:8083/deleteproductbyid/1). The app works when I change the annotation for the method to #GetMapping but that causes other issues.
Here's the relevant code:
package com.democrudexample.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.democrudexample.model.Product;
import com.democrudexample.services.CrudService;
#RestController
#RequestMapping("/")
public class CrudRestController {
#Autowired
private CrudService service;
#GetMapping("/getproductlist")
#CrossOrigin(origins = "http://localhost:4200")
public List<Product> fetchProductList() {
List<Product> products = new ArrayList<Product>();
//logic to fetch list from database
products = service.fetchProductList();
return products;
}
#PostMapping("/addproduct")
#CrossOrigin(origins = "http://localhost:4200")
public Product saveProduct(#RequestBody Product product) {
return service.saveProductToDB(product);
}
#GetMapping("/getproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public Product fetchProductById(#PathVariable int id) {
return service.fetchProductById(id).get();
}
#DeleteMapping(value = "/deleteproductbyid/{id}")
#CrossOrigin(origins = "http://localhost:4200")
public String deleteProductById(#PathVariable int id) {
return service.deleteProductById(id);
}
}
package com.democrudexample.services;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.democrudexample.model.Product;
import com.democrudexample.repository.CrudRepo;
#Service
public class CrudService {
#Autowired
private CrudRepo repo;
public List<Product> fetchProductList(){
return repo.findAll();
}
public Product saveProductToDB(Product product) {
return repo.save(product);
}
public Optional<Product> fetchProductById(int id) {
return repo.findById(id);
}
public String deleteProductById(int id) {
String result;
try {
repo.deleteById(id);
result = "Product sucessfully deleted";
System.out.println(result);
}catch(Exception e) {
result = "Product id is not valid";
System.out.println(result);
}
return result;
}
}
EDIT: I commented out the result and everything related to it in the deleteProductById method and it seems to be working just fine now. After having looked at the console, the error seems to have been some issues with parsing the text.
By annotating the method as #DeleteMapping, you are making this a HTTP DELETE operation. Refer this documentation for more details about different HTTP requests.
However, when you access an URL in browser, browser always sends a GET request, whereas your Resource is expecting a DELETE request. Hence you are getting the error.
You can use tools like Postman or you can write a small code in Javascript to send a DELETE request to the server.

Spring boot data not uploaded

I build spring boot application, but the problem is I want to upload images on the web browser but it does not work, I run the app on IntelliJ IDEA, here is the code: https://github.com/rmalav15/siamese-tf-java
please help, here is the code that backs the error (Unable to Enroll Due to some error)
package com.tensorflow.siamese.controllers;
import com.tensorflow.siamese.models.User;
import com.tensorflow.siamese.services.EnrollmentService;
import com.tensorflow.siamese.services.ImageProcessingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
#RestController
#RequestMapping("/enroll")
#Slf4j
public class EnrollmentController {
#Value("${images.save.path:src/main/resources/Images}")
private String path;
#Autowired
private EnrollmentService enrollmentService;
#RequestMapping(value = "/new", method = RequestMethod.POST)
ResponseEntity enrollNew(#RequestParam("name") String name,
#RequestParam("files") List<MultipartFile> images) {
try {
List<Path> imagePaths = new ArrayList<>();
for (MultipartFile file : images) {
imagePaths.add(ImageProcessingService.write(file, path));
}
User user = enrollmentService.enrollNew(imagePaths, name);
return ResponseEntity.ok(user);
} catch (Exception e) {
log.debug("Exception in enrollNew Apia", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Unable to Enroll Due to some error.");
}
}
}

Spring WebFlux File Upload: Unsupported Media Type 415 with Multipart upload

I'm running into some issues handling a file upload using spring's reactive framework. I think I'm following the docs, but can't get away from this 415 / Unsupported Media Type issue.
My controller looks like below (as per the example here: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-multipart-forms)
package com.test.controllers;
import reactor.core.publisher.Flux;
import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.codec.multipart.Part;
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 TestController {
#RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<String> uploadHandler(#RequestBody Flux<Part> parts) {
return parts
.filter(part -> part instanceof FilePart)
.ofType(FilePart.class)
.log()
.flatMap(p -> Flux.just(p.filename()));
}
}
POSTing to this endpoint though, always gives me the same output:
curl -X POST -F "data=#basic.ppt" http://localhost:8080/upload
---
"Unsupported Media Type","message":"Content type 'multipart/form-data;boundary=------------------------537139718d79303c;charset=UTF-8' not supported"
I've attempted to use #RequestPart("data") too, but get a similar Unsupported Media Type error, albeit with the content type of the file.
It seems that Spring is having issues converting these to a Part..? I'm stuck - any help is apprecitated!
Well, it's not a direct answer for your question, because I use functional endpoints, but I hope it will help you somehow.
import org.springframework.context.annotation.Bean;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.codec.multipart.Part;
import org.springframework.stereotype.Controller;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import java.io.File;
import java.util.Map;
import static org.springframework.web.reactive.function.BodyInserters.fromObject;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
#Controller
public class FileUploadController {
#Bean
RouterFunction<ServerResponse> apiRoutes() {
return nest(path("/api"),
route(POST("/upload"), fileUpload()));
}
private HandlerFunction<ServerResponse> fileUpload() {
return request -> {
return request.body(BodyExtractors.toMultipartData()).flatMap(parts -> {
Map<String, Part> map = parts.toSingleValueMap();
final FilePart filePart = (FilePart) map.get("file");
final String dir = "C:\\JDeveloper\\mywork\\Spring\\SpringTest\\webflux-file-upload\\uploaded";
filePart.transferTo(new File(dir + "/" + filePart.filename()));
return ServerResponse.ok().body(fromObject("ok, file uploaded"));
}
);
};
}
}
You can upload a file with curl like this:
curl -F "file=#C:\Users\Wojtek\Desktop\img-5081775796112008742.jpg" localhost:8080/api/fileupload
Thanks #kojot for your answer, but in this case I discovered the issue was my inclusion of spring-webmvc transiently in addition to spring-webflux. Your solution would likely have worked too, but I wanted to stick with the Controller style so ended up forcibly excluding spring-webmvc from my build.gradle:
configurations {
implementation {
exclude group: 'org.springframework', module: 'spring-webmvc'
}
}
After that it worked as documented.

Accessing request payload in V2 DialogFlow fulfillment webhook

I'm trying to parse the request sent to a java based fulfillment in V2 of the API. I can't find any example documentation in Java for doing this in V2 of the API (com.google.cloud:google-cloud-dialogflow:0.38.0-alpha dependency in my project).
So far I've got as far as writing a very basic Spring MVC controller to accept the request.
How can I parse out the payload in the request, e.g. the parameters that dialog flow sent ?
import com.google.cloud.dialogflow.v2beta1.WebhookRequest;
import com.google.cloud.dialogflow.v2beta1.WebhookResponse;
import com.google.protobuf.Descriptors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
#RestController
#RequestMapping("test")
public class TestRequestRestController {
private static final Logger log = LoggerFactory.getLogger(TestRequestRestController.class);
#PostMapping("test1t")
public WebhookResponse getTest1(WebhookRequest request) {
System.out.println(request.toString());
return WebhookResponse.newBuilder().setFulfillmentText("Example reply 1 ").build();
}
}
Not sure about WebhookRequest and WebhookResponse.
The code below code might help you.
import org.springframework.http.HttpEntity;
#PostMapping("test1t")
public String getTest1(HttpEntity<String> httpEntity) {
String reqObject = httpEntity.getBody();
System.out.println("request json object = "+reqObject);
//Get the action
JSONObject obj = new JSONObject(reqObject);
String action = obj.getJSONObject("result").getString("action");
//Get the parameters
JSONObject params = obj.getJSONObject("result").getJSONObject("parameters");
String response = "Hello from Java.";
return "{'speech': '"+response+"', 'displayText':'"+response+"'}";
}

spring boot multipartFile with application/octet-stream throws exception

I wanted to build a simple Rest api using Spring boot which accepts any given file and then performs some operations on it . I went through the spring examples on multipartFile https://spring.io/guides/gs/uploading-files/ and I decided to follow the same approach. The files that will be uploaded through my rest api will have some specific extension. So,i gave the content-type as application/octet-stream . When I try to run my unit test cases for the same,
I always get the exception of
nested exception is org.springframework.web.multipart.MultipartException: The current request is not a multipart request
This exception does not appear if the content type is text/plain or if there is no 'consumes' parameter in the requestMapping.
My controller code looks as follows :
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
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.RequestPart;
import org.springframework.web.multipart.MultipartFile;
#Controller
#RequestMapping("/v1/sample")
public class SampleController {
private static Logger log = LoggerFactory.getLogger(SampleController.class);
#RequestMapping(path = "/{id}/upload",
consumes = {MediaType.APPLICATION_OCTET_STREAM_VALUE},
method = RequestMethod.POST)
public ResponseEntity<String> uploadfile(#PathVariable String id,
#RequestParam("file") MultipartFile upgradeFile) {
log.info("Obtained a upload request for the id {}",id );
return new ResponseEntity<String>("file upload has been accepted.",
HttpStatus.ACCEPTED);
}
}
And my unit test snippet is as follows :
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.stellapps.devicemanager.fota.Application;
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#SpringApplicationConfiguration(classes = Application.class)
#EnableWebMvc
public class ControllerTest {
#Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
#Before
public void mockMvcBuilder() {
this.mockMvc = webAppContextSetup(webApplicationContext).build();
}
#Test
public void test_ValidPayload() {
String uri = "/v1/sample/1234/upload";
Path path = Paths.get("src/test/resources/someFile");
try {
byte[] bytes = Files.readAllBytes(path);
MockMultipartFile multipartFile =
new MockMultipartFile("file", "someFile.diff", "application/octet-stream", bytes);
mockMvc.perform(fileUpload(uri).file(multipartFile).contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE))
.andExpect(status().isAccepted());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
If I use text/plain as the content-type and i give a normal text file, it goes through fine. If I add the content-type as application/octet-stream it throws the following exception
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.web.multipart.MultipartException: The current request is not a multipart request
at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.assertIsMultipartRequest(RequestPartMethodArgumentResolver.java:204)
at org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver.resolveArgument(RequestPartMethodArgumentResolver.java:129)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:99)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:817)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:731)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
How Do I make my request accept application/octet-stream and what changes should I make to the test case to ensure it succeeds.
UPDATE:
Removing the consumes header and by not specifying the content-type in MockPartFile is one of the way to upload a file. I suppose by default the controller takes it as application/octet-stream
UPDATE:
Thank you for the response. I was using an earlier version of spring (1.3.1) and after going through the answer, I updated my spring version and the test case to match it and It started working.
Try below steps
Remove the consumes from the RequestMapping attributes.
MockMultipartFile multipartFile = new MockMultipartFile("file","somename","multipart/form-data", fileinputstream);
Change to MockMvc:
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/v1/sample/1234/payload")
.file(multipartFile)
.andExpect(status().isOk());
For help check
Upload file using Spring mvc and MockMVC
EDIT:
I've tried a sample spring-boot-rest app with your scenario. Seems application/octet-stream is no issue. Please check my repo
https://github.com/satya-j/boot-file-manager

Categories