FIXED Send POST request to server from client, Springboot - java

I am trying to send a post request, but springboot doesnt seem to recieve it.
My code:
Serverside reader
#RestController
public class MessageService {
#PostMapping(path = "/online")
public ResponseEntity<?> getResponse(){
System.out.println("Post Recieved");
return new ResponseEntity<>(HttpStatus.OK);
}
}
Client
private String url = "http://127.0.0.1:8090";
public static void main(String[] args) throws IOException {
SpringApplication.run(Client.class, args);
new StartupService().init();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
StartupService/ POST Sender
public void init() throws IOException {
String query = "Body";
Client client = new Client();
HttpURLConnection urlConn;
URL mUrl = new URL(client.getUrl()+ "/online");
urlConn = (HttpURLConnection) mUrl.openConnection();
//query is body
urlConn.addRequestProperty("Content-Type", "application/" + "POST");
urlConn.setDoOutput(true);
urlConn.setRequestProperty("Content-Length", Integer.toString(query.length()));
urlConn.getOutputStream().write(query.getBytes(StandardCharsets.UTF_8));
System.out.println("Post Sent");
}
I tried sending a POST request via Postman, which worked as expected and gave me the console output. But the POST from code isn't recieved from the server.

FIXED: I used a simpler method to send a POST:
javaClient userClient = new Client();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(userClient.getUrl()+ "/online"))
.POST(HttpRequest.BodyPublishers.ofString(query))
.build();
HttpResponse<String> response = client.send(
request,
HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
System.out.println("Post Sent");

Related

Getting Request method 'GET' not supported in java using OkHTTP Client and HttpsURLConnection

As I need to send data through post for initiating the API, but getting get not supported error. Even I'm using post method ,Please suggest where I did mistake. I have tried OkHTTPClient and HTTPsURL connection, still getting same error
Error: **{"timestamp":"2021-03-23T06:26:43.508+0000","status":405,"error":"Method Not Allowed","message":"Request method 'GET' not supported","path":"/stsBankResponse/"}**
When I directly hit the URL in browser that time also getting method not allowed ,its valid error but programmatically using Post only even though same error
JSONObject jsobj=new JSONObject();
jsobj.put("authmode", "Abc");
JSONArray jaarray = new JSONArray();
jaarray.put(jsobj);
JSONObject mainObj = new JSONObject();
mainObj.put("bankResponseDtl", jaarray);
String str_jsonparams = String.valueOf(mainObj);
System.out.println("PU_Auth str_jsonparams->"+str_jsonparams);
String proxyhost=common_utility.getProxyHost();
String proxyport=common_utility.getProxyPort();
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyhost, new Integer(proxyport)));
OkHttpClient client = new OkHttpClient();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(30, TimeUnit.SECONDS);
builder.writeTimeout(30, TimeUnit.SECONDS);
builder.proxy(proxy);
client = builder.build();
RequestBody body = RequestBody.create(JSON, str_jsonparams);
Request request = new Request.Builder()
.url(common_utility.getEmandateServerResponeURL())
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
call.cancel();
System.out.println("ECEEEEE"+e);
}
#Override
public void onResponse(Call arg0, Response arg1) throws IOException {
}
});

Retrofit: Making Web Requests to Internal APIs

I want to make a request to my organisation api's. The request contains Headers, UserName, Password, & Cookie for session management.
Below is the actual code (in HttpClient) which I want to rewrite using Retrofit. I have heard that HttpClient libraries have been deprecated or someting so have opted Retrofit. I expect the response with 200 status code.
public static CookieStore cookingStore = new BasicCookieStore();
public static HttpContext context = new BasicHttpContext();
public String getAuth(String login,String password) {
String resp = null;
try {
String url = DOMAIN+"myxyzapi/myanything";
context.setAttribute(HttpClientContext.COOKIE_STORE, cookingStore);
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(url);
String log = URLEncoder.encode(login, "UTF-8");
String pass = URLEncoder.encode(password, "UTF-8");
String json = "username="+log+"&password="+pass+"&maintain=true&finish=Go";
StringEntity entity = new StringEntity(json);
post.setEntity(entity);
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse response = client.execute(post,context);
resp = EntityUtils.toString(response.getEntity());
accountPoller();
} catch(Exception a) {
log.info("Exception in authentication api:"+a.getMessage().toString());
}
return resp;
}
Below is my code where I can't figure out how to pass the context with request. HttpResponse response = client.execute(post,**context**); using retrofit.
I don't even know if I have made my retrofit request right.
try {
String log = URLEncoder.encode(login, "UTF-8");
String pass = URLEncoder.encode(password, "UTF-8");
RequestBody formBody = new FormBody.Builder()
.add("username=", xyz)
.add("password=", mypass)
.add("&maintain=", "true")
.add("finish=", "Go")
.build();
String url = www.xyz.com+"myxyzapi/myanything";
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).post(formBody).addHeader("Content-Type", "application/x-www-form-urlencoded").build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
final String myresp = response.body().string();
}
}
});
} catch(Exception a) {
a.getMessage();
}
You have to catch exception and use this class.
retrofit2.HttpException
retrofit2
Class HttpException
int
code()
HTTP status code.
String
message()
HTTP status message.
Response
response()
The full HTTP response.

How to develop a spring rest web service in accessing external API?

I want to develop the spring rest web service which accesses the external API when user sends request. User sends a json request and set of request headers to the web service and web service should authenticate the user and call the eternal API. External API response should be given to the user as the response body. This is what I want to happen basically.
//Authenticate to access API
public class HotelbedsAuthentication {
final String hotelEndpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/";
private String request;
private static final String apiKey="enter given api key for free";
private static final String secretKey="free key";
private String signature=org.apache.commons.codec.digest.DigestUtils.sha256Hex(apiKey + secretKey + System.currentTimeMillis() / 1000);
public HttpsURLConnection findHotels(){
HttpsURLConnection connection = null;
try{
URL url = new URL(hotelEndpoint+getRequest());
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestProperty("X-Signature", signature);
con.setRequestProperty("Api-Key", apiKey);
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Accept-Encoding", "gzip");
con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput (true);
connection=con;
}catch(Exception error ){
System.out.println("An error occured "+error);
}
return connection;
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
}
//Rest Controller
public class FindHotelController {
HotelbedsAuthentication token = new HotelbedsAuthentication();
#RequestMapping(value="hotels",method=RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public HotelAvailability findHotel(#RequestBody JSONObject request){
HttpsURLConnection connection;
File pathDir = new File("C:/Users/User/workspace/SpringRestSample/src/main/java");
JCodeModel codeModel = new JCodeModel();
JSONObject response= new JSONObject();
HotelAvailability sample= new HotelAvailability();
//String userRequest="{\"stay\": {\"checkIn\": \"2018-01-29\",\"checkOut\": \"2018-01-31\",\"shiftDays\": \"2\"},\"occupancies\": [{\"rooms\": 1,\"adults\": 2,\"children\": 1,\"paxes\": [{\"type\": \"AD\",\"age\": 30},{\"type\": \"AD\",\"age\": 30},{\"type\": \"CH\",\"age\": 8}]}],\"hotels\": {\"hotel\": [1067,1070,1075,135813,145214,1506,1508,1526,1533,1539,1550,161032,170542,182125,187939,212167,215417,228671,229318,23476]}}";
try{
token.setRequest("hotels");
connection= token.findHotels();
//Read request and embed to url
OutputStream os = connection.getOutputStream();
os.write(request.toString().getBytes("UTF-8"));
os.close();
// read the response
InputStream in = new BufferedInputStream(connection.getInputStream());
String result = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
JSONObject jsonObject = new JSONObject(result);
response=jsonObject;
GenerationConfig config = new DefaultGenerationConfig() {
#Override
public boolean isGenerateBuilders() {
return true;
}
public SourceType getSourceType(){
return SourceType.JSON;
}
};
SchemaMapper mapper =new SchemaMapper(new RuleFactory(config, new GsonAnnotator(config), new SchemaStore()), new SchemaGenerator());
mapper.generate(codeModel, "HotelAvailability","com.sample.model",response.toString());
codeModel.build(pathDir);
ObjectMapper objectMapper = new ObjectMapper();
sample = objectMapper.readValue(response.toString(), HotelAvailability.class);
in.close();
connection.disconnect();
}catch(Exception ex){
System.out.println(ex);
}
System.out.println(sample);
return sample;
}
}
What you're looking for is an API Gateway or a simple router based on your requirements. If you need to make changes to the response, you need a Gateway. If you're looking to simply pass the request then you need a router.
There are many ways to do this, but as always, Spring has already built a tool for that. check out Zuul. This will allow you to integrate with an Authentication provider and then delegate requests to microservices.
Gateway
https://www.intertech.com/Blog/spring-integration-tutorial-part-8-gateways/
OAuth Provider
https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_authserver
Router
https://cloud.spring.io/spring-cloud-netflix/multi/multi__router_and_filter_zuul.html

Apache Http Client overriding user defined content-length header

I am using Apache Http Client to upload a file. When I set the content-length to incorrect file-size.
The content length header gets overridden by the file size.
Thus causing acceptance test to fail as it allows to upload the file because the content-length is equal to file-size.
public class RestClient {
Client client = null;
public RestClient() {
client = Client.create();
//client.addFilter(new LoggingFilter(System.out));
}
public ClientResponse postData(String url, Map headerMap) throws IOException {
ClientResponse response = null;
try {
WebResource webResource = client.resource(url);
Builder requestBuilder = webResource.getRequestBuilder();
Iterator it = headerMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
requestBuilder = requestBuilder.header(pair.getKey().toString(), pair.getValue());
}
if (headerMap.get("filename") != null) {
ClassLoader cl = getClass().getClassLoader();
InputStream fileInStream = cl.getResourceAsStream(headerMap.get("filename").toString());
MessageDigest md = MessageDigest.getInstance("SHA-256");
requestBuilder = requestBuilder.entity(fileInStream);
}
response = requestBuilder.header("Expect", new String("100-continue"))
.post(ClientResponse.class);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
public ClientResponse getData(String url) {
ClientResponse response = null;
WebResource webResource = client.resource(url);
response = webResource.get(ClientResponse.class);
return response;
}
}
Currently headermap has required headers (Content-Length,Content-Type etc.)
Can I set Content-Length explicitly without the client internally overriding it. Any http client is ok.
Any self-respecting HTTP client should do the same. HttpURLConnection certainly does. Your test is invalid. The content-length must match the actual number of bytes transmitted.

authentication with Java and apache HttpClient 4.5.1

my problem is, that i don't get, how to log in with Java and Apache HttpComponents (HttpClient v4.5.1) into a specific site: Site im trying to log in. I have the username (test_admin) and the password (testing) to log in but i think this is not enough and i need something more. I think this has something to do with the field security_token i see when i make a get request to the uri, but i dont know how to keep that or how to save that and what to do with it afterwards. There is also a hidden input field with the name login-ticket, but i dont know what's that for either. I want to login, because i need to see the courses and add some new ones. After trying with several code implementations im stick with this code:
public static void setGet(CloseableHttpClient httpClient) throws UnsupportedOperationException, IOException
{
HttpGet httpGet = new HttpGet("http://demo.studip.de/dispatch.php/admin/courses");
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
System.out.println("GET Response Status:: "
+ httpResponse.getStatusLine().getStatusCode());
showEntity(httpResponse,httpResponse.getEntity());
}
public static HttpEntity setParam(int count, String[] params, String[] values)
{
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
for (int i = 0; i < count; i++)
{
formparams.add(new BasicNameValuePair(params[i],values[i]));
System.out.println("Paramater------------------> "+params[i]+" Values-------------> "+values[i]);
}
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
return entity;
}
public static void setPost(HttpClient httpC) throws ClientProtocolException, IOException
{
HttpPost httppost = new HttpPost("http://demo.studip.de/dispatch.php/admin/courses");
//String[] params = {"loginname", "password"};
//String[] values = {"test_admin", "testing"};
//HttpEntity entity = setParam(2, params, values );
HttpResponse response = httpC.execute(httppost);
System.out.println("POST Response Status:: "
+ response.getStatusLine().getStatusCode());
showEntity(response, response.getEntity());
}
public static void showEntity(HttpResponse httpResp, HttpEntity httpClient) throws IOException
{
httpClient = httpResp.getEntity();
if (httpClient != null)
httpClient = new BufferedHttpEntity(httpClient);
System.out.print(EntityUtils.toString(httpClient));
}
public static void main(String[] args) throws InterruptedException, IOException {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("test_admin", "testing"));
CloseableHttpClient hc =
HttpClientBuilder.create().setDefaultCredentialsProvider(credentialsProvider).build();
setGet(hc);
// HttpClient httpclient = HttpClients.createDefault();
setPost(hc);
setGet(hc);
}
The problem now ist that i get everytime the same answer from the server i only see the login page in the response, where the server asks me to login with username and password.
Which code you get from the server 401,403,301,302 or 200?

Categories