friend, I'm using RestController from spring data to consume data from external API.
When I use PostMan to get data, I get this 404 error code.
But if I use direct URL with a header on POSTMAN I get the correct data and response code 200
Could you please help me
Console Intelij
2018-11-13 17:30:42.334 WARN 11820 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : No mapping for GET /toto
This my Controller Class
package com.controller;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.json.Json;
#RestController
#CrossOrigin("*") // pour gere les erreu d'ente ex: Orig
public class FlightRestServives {
private static Logger logger = Logger.getLogger(FlightRestServives.class.getName());
#Autowired
private RestTemplate restTemplate;
String serviceURL = "https://api.klm.com/opendata/flightoffers/reference-data?country=NL";
public FlightRestServives() {
}
//Consuming a service by GET method
// #GetMapping("/test")
#RequestMapping(
value = "/toto",
headers = {
"api-key=xmc3vburw886j9zqcsfrdu2t",
"AFKL-TRAVEL-Country=NL",
"AFKL-TRAVEL-Host=KL",
"X-Originating-IP=46.193.67.48"}
/*produces = "application/json",
consumes = "application/json",
headers = {
"api-key=xmc3vburw886j9zqcsfrdu2t",
"AFKL-TRAVEL-Country=NL",
"AFKL-TRAVEL-Host=KL",
"X-Originating-IP=46.193.67.48"}*/
)
public Json getAvailableOperations() {
logger.debug("Flight");
HttpHeaders headers = new HttpHeaders();
headers.add("api-key", "Keyyy");
headers.add("AFKL-TRAVEL-Country", "NL");
headers.add("AFKL-TRAVEL-Host", "KL");
headers.add("X-Originating-IP", "46.193.67.48");
HttpEntity requestEntity = new HttpEntity(headers);
logger.debug("request entities are: " + requestEntity);
return restTemplate.getForObject(serviceURL, Json.class);
/*return restTemplate
.exchange(
serviceURL,
HttpMethod.GET,
requestEntity,
Json.class
);*/
}
}
Related
import com.google.gson.Gson;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import preproject.underdog.answer.dto.answer.AnswerPostDto;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#WebMvcTest(value = AnswerController.class)
//#AutoConfigureRestDocs
#MockBean(JpaMetamodelMappingContext.class)
public class AnswerController {
#Autowired
private MockMvc mockMvc;
#Autowired
private Gson gson;
#Test
#DisplayName("답변 글 작성 테스트")
void postAnswer() throws Exception {
AnswerPostDto post = new AnswerPostDto("테스트", 1L, 1L);
String content = gson.toJson(post);
ResultActions actions =
mockMvc.perform(
post("/answers")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(content)
);
actions
.andExpect(status().isCreated());
}
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import preproject.underdog.answer.dto.answer.AnswerPostDto;
import preproject.underdog.answer.dto.answer.AnswerRespDto;
import preproject.underdog.answer.mapper.AnswerMapper;
import preproject.underdog.answer.service.AnswerService;
import javax.validation.Valid;
import java.time.LocalDateTime;
#RestController
#RequestMapping("/answers")
#Validated
#RequiredArgsConstructor
public class AnswerController {
private final AnswerService answerService;
private final AnswerMapper answerMapper;
#PostMapping
public ResponseEntity postAnswer(#Valid #RequestBody AnswerPostDto answerPostDto) {
AnswerRespDto answerRespDto = new AnswerRespDto(1L,"테스트",1L,1L,1L, LocalDateTime.of(2023, 4, 3, 3, 3, 0),LocalDateTime.of(2023, 4, 3, 3, 3, 0));
return new ResponseEntity<>(answerRespDto, HttpStatus.CREATED);
}
Here's my codes first,
I tried make Rest Docs first, but I faced a lot of errors, so I just started to try pass the MockMVC test first.
So I gotta got 201 response from that, but I only got 404 error
here's my log.
MockHttpServletRequest:
HTTP Method = POST
Request URI = /answers
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"49"]
Body = {"content":"테스트","userId":1,"questionId":1}
Session Attrs = {}
Handler:
Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 404
Error message = null
Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
#PostMapping
public ResponseEntity postAnswer(#Valid #RequestBody AnswerPostDto answerPostDto) {
return new ResponseEntity<>(HttpStatus.CREATED);
}
I even tried to changed the code to get only 201 response like this
but it still gave me 404 error
What should I do?? thanks
Getting the following exception while executing a GET against RestTemplate::exchange(). It's a pretty simple public endpoint. I have included the controller and the DTO. The exception notes 'content type [text/html]' - I have read in other articles that this may be related to error response in XML rather than a response JSON. I have looked a little deeper into exception with no success ... again a pretty simple GET endpoint ?? Any help is appreciated.
Public Endpoint
http://catfact.ninja/fact
Exception
2022-01-07 11:18:40.896 ERROR 22564 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in
context with path [] threw exception [Request processing failed; nested exception
is org.springframework.web.client.RestClientException: Error while extracting response
for type [class com.example.demo.CatDTO] and content type [text/html]; nested exception
is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('<' (code 60)): expected a valid value (JSON String, Number,
Array, Object or token 'null', 'true' or 'false'); nested exception
is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)):
expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (PushbackInputStream); line: 1, column: 2]] with root cause
DTO Class
public class CatDTO {
public String fact;
public int length;
}
Controller Class
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
#RestController
public class CatWebServiceController {
#Autowired
RestTemplate restTemplate;
String url = "http://catfact.ninja/fact";
#RequestMapping(value = "/cat")
public ResponseEntity<CatDTO> getCatFact() throws IOException {
System.out.println("Inside: CatWebServiceController::getCatFact()");
CatDTO catDTO;
String urlTemplate = UriComponentsBuilder.fromHttpUrl(url)
.encode()
.toUriString();
// Just a little test
ObjectMapper mapper = new ObjectMapper();
File f = new File("C:\\macgowan\\project\\test\\demo\\response.json");
CatDTO catDTO2 = mapper.readValue(f, CatDTO.class);
// Create the headers
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
//Add the Jackson Message converter
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
// Note: here we are making this converter to process any kind of response,
// not only application/*json, which is the default behaviour
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
messageConverters.add(converter);
restTemplate.setMessageConverters(messageConverters);
ResponseEntity<CatDTO> r = null;
try
{
r = restTemplate.exchange(urlTemplate,
HttpMethod.GET,
entity,
CatDTO.class);
System.out.println("Inside: It worked");
}
catch (HttpClientErrorException exc)
{
String errorMessage = exc.getResponseBodyAsString();
System.out.println("Inside: HttpClientErrorException");
}
catch (Exception exc)
{
String errorMessage = exc.getMessage();
System.out.println("Inside: Exception");
}
return r;
}
}
Spring Init
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
#SpringBootApplication
public class DemoApplication
{
public static void main(String[] args)
{
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
}
Try https://catfact.ninja/fact instead of http://catfact.ninja/fact
What you are receiving is literally:
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
so you where right that your error is related to a response in XML
to quickly find out, you can intercept the response:
restTemplate.getInterceptors().add((httpRequest, bytes, clientHttpRequestExecution) -> {
ClientHttpResponse response=clientHttpRequestExecution.execute(httpRequest, bytes);
String text = new String(response.getBody().readAllBytes(), StandardCharsets.UTF_8);
System.out.println(text);
return response;
});
I'm very new to web-service dev and I'm trying to make a POST request to an API using Jersey. The issue is I think I'm mixing documentation and example I'm finding online between client & server. I'm pretty sure that it's simple but I can't figure out why my code is failing.
Here is my main Class :
import deliveryPayload.Payload;
import jakarta.ws.rs.*;
import jakarta.ws.rs.client.*;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;
import org.apache.commons.lang3.StringUtils;
import responsePayload.ResponsePayload;
import java.net.URI;
import java.util.*;
#Path("/hook")
public class Hook {
private static final String apiToken = "myToken";
private static final String domain = "url";
private static final String apiUrl = "https://" + domain + "/api/v1/";
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response eventHook(String body, #HeaderParam("Pass") String password) {
ObjectMapper objectMapper = new ObjectMapper();
Payload payload = new Payload();
try {
payload = objectMapper.readValue(body, Payload.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
EventsItem event = payload.getData().getEvents().get(0);
Actor actor = event.getActor();
Response response = ClientBuilder.newClient()
.target(getBaseURI())
.path("apps/" + "someID" + "/users")
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, apiToken)
.post(Entity.entity(actor, MediaType.APPLICATION_JSON));
return response;
}
}
I'm getting this error Parse Error: The response headers can't include "Content-Length" with chunked encoding when using Postman.
Thanks for any help !
I need some help with writing a controller to consume a JSON response from a payment system (Realex).
So far, I have the following from the Realex documentation but can't figure out how to write the controller - i'm new to Spring Boot/Spring MVC.
RealexHpp realexHpp = new RealexHpp("Shared Secret");
HppResponse hppResponse = realexHpp.responseFromJson(responseJson);
// responseJson will be the Java variable containing the JSON response string
String result = hppResponse.getResult();
String message = hppResponse.getMessage();
String authCode = hppResponse.getAuthCode();
So far, i have written:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.realexpayments.hpp.sdk.RealexHpp;
import com.realexpayments.hpp.sdk.domain.HppResponse;
#Controller
public class PaymentController {
#RequestMapping(value = "/enrolment/confirmation", method = RequestMethod.GET, consumes = "text/plain")
public String process(#RequestBody String responseJson, Model model) throws Exception {
RealexHpp realexHpp = new RealexHpp("secret");
HppResponse hppResponse = realexHpp.responseFromJson(responseJson);
// responseJson will be the Java variable containing the JSON response string
String result = hppResponse.getResult();
String message = hppResponse.getMessage();
String authCode = hppResponse.getAuthCode();
System.out.println("Result: "+result);
System.out.println("Message: "+message);
System.out.println("AuthCode: "+authCode);
model.addAttribute("result", result);
model.addAttribute("message", message);
model.addAttribute("authcode", authCode);
return "enrolment/confirmation";
}
}
Looks like Spring MVC isn't the right tool here.
See: https://github.com/realexpayments/rxp-hpp-java
It's expecting you to use their SDK to generate the repsonseJson:
HppRequest hppRequest = new HppRequest()
.addAmount(100)
.addCurrency("EUR")
.addMerchantId("merchantId");
RealexHpp realexHpp = new RealexHpp("mySecret");
String requestJson = realexHpp.requestToJson(hppRequest);
You might want to be using Spring MVC to capture the parameters for the request.
I am new to using Spring mvc4 annotation . In all i want to do is using spring mvc as a web service . so i would be thankful if anyone could provide me a solution for it.
My android code is as:
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httppost = new HttpPost( "http://localhost:8080/datarequest");
JSONObject json = new JSONObject();
json.put("action", "check_login");
json.put("username","name");
json.put("password", "password");
JSONArray postjson = new JSONArray();
postjson.put(json);
httppost.setHeader("json", json.toString());
httppost.getParams().setParameter("jsonpost", postjson);
System.out.println(postjson);
HttpResponse response = httpclient.execute(httppost);
so far i wrote the web service as:
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
#Controller
#RequestMapping("/datarequest")
public class HelloController {
#RequestMapping(method = RequestMethod.GET)
public String getMethod(ModelMap model) {
System.out.println("GET");
return "hello";
}
#RequestMapping(method = RequestMethod.POST, produces = "application/json")
public String getMethod(ModelMap model) {
System.out.println("POST");
System.out.println("here i want to print json data send from the android ");
return "hello";
}
}
You can use #RequestBody and map it to required class structure. You can refer this SO question #RequestBody and #ReponseBody spring.
To test, you can map it to String. See below example.
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestHeader;
#RequestMapping(method = RequestMethod.POST, produces = "application/json")
public #ResponseBody String getMethod(#RequestHeader(value="json") String headerStr) {
System.out.println("POST");
System.out.println(s);
return "hello";
}
You can add below maven entry in your pom.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>