I have a question about java web applications.
Is there a way to map url: index.jsp?lng=en to: index/en?
Take the host name from the request object if you are getting HttpServletRequest OR you can use regex to get the host name. en is a request parameter value which you can get using request.getParameter("lng")
URL aURL = new URL("index.jsp?lng=en");
System.out.println("hostname = " + aURL.getHost()); //index
then return String with hostName + "/" + paramValue
Related
I need to populate a database with the fields of the HTTP requests based on if the sender IP is valid or not.
For example if someone make a GET request on my IP with that:
/test/demo.php?name1=value1&name2=value2
How can I receive it so I can handle it and perform actions like:
Get the ip of the sender (And validate it - just confronting it with a list -)
Recognize the type of the Request
Extrapolate the fields (value1 and value2) and save them in variables
I'm using java.net.http package
You can't perform that using package java.net.http because you need to create an http server not an http client. To achieve that, you need HttpServer which is found in package com.sun.net.httpserver.
The first thing is to create a new instance of HttpServer :
final int port = 3000;//You can change with your port number you need
final HttpServer httpServer = HttpServer.create(new InetSocketAddress(port), 0);
System.out.println("Listening port : " + port);
Then, configure an http context. The first parameter accepts the route you defines and the second parameter accepts the http handler in which you can extract all your data that you need to store in your database.
httpServer.createContext("/test/demo.php", buildHttpHandler());//buildHttpHandler is to create
What contains the function buildHttpHandler()? :
Each time where route /test/demo.php is called, the content of arrow function is called. Here, we attempt only to create a simple page html and serves it to the http client. But before responding http client, we need to extract all data you need (ip, request type and parameters).
return httpExchange -> {
final String html = "<!DOCTYPE html>\n" +
"<html>\n" +
" <head>\n" +
" <title>Page</title>\n" +
" <meta charset='utf-8'/>\n" +
" </head>\n" +
" <body>Ok</body>\n" +
"</html>";
//Function to create
extractData(httpExchange);
httpExchange.getResponseHeaders().set("Content-Type", "text/html; charset=utf-8");
httpExchange.sendResponseHeaders(200, html.length());
final OutputStream outputStream = httpExchange.getResponseBody();
outputStream.write(html.getBytes(StandardCharsets.UTF_8));
outputStream.close();
};
What contains extractData() function?
In this function we will extract the data you need.
final String ip = getClientIp(httpExchange);
System.out.println("IP : " + ip);
final String requestType = httpExchange.getRequestMethod();
System.out.println("Request type : " + requestType);
final Map<String, String> parameters = extractParameters(httpExchange);
displayParameters(parameters);
Extracting ip client is more complicated because sometime client uses proxy that's why we create a dedicated function getClientIp() to extract the ip.
In this function, we attempt to extract firstly proxy ip. If not found, we extract standard ip from remote :
final String ip = getProxyIp(httpExchange);
return ip == null ? httpExchange.getRemoteAddress().getAddress().getHostAddress() : ip;
To extract proxy ip, we create another function getProxyIp(). It attempts to extract the ip provided from x-forwarded-for request header.
final List<String> ips = httpExchange.getRequestHeaders().get("x-forwarded-for");
return ips == null ? null : ips.get(ips.size() - 1);
I don't know what do you mean with extrapolating fields but you can store all data in a Map variable. The key will be the name of parameter and the value will be the value of parameter. But this is complicated also because we need to parse the string value from name1=value1&name2=value2. So, we create a new function extractParameters(). It contains :
final String query = httpExchange.getRequestURI().getQuery();
final Map<String, String> parameters = new HashMap<>();
if (query != null) {
final String[] firstParts = query.split("&");
for (final String firstPart : firstParts) {
final String[] secondParts = firstPart.split("=");
final String name = secondParts[0];
final String value = secondParts.length > 1 ? secondParts[1] : null;
parameters.put(name, value);
}
}
return parameters;
You notice maybe what is displayParameters() content. It just attempts to display, parameters retrieved from extractParameters().
for (final Map.Entry<String, String> parameter : parameters.entrySet()) {
System.out.println("Parameter key : " + parameter.getKey());
System.out.println("Parameter value : " + parameter.getValue());
}
And finally don't forget to start the http server :
httpServer.start();
You can check for a full code here https://gist.github.com/razafinarivohanania/24fe0986ea5868097404f2a758131823
When you test it, you can get something like :
IP : 127.0.0.1
Request type : GET
Parameter key : name2
Parameter value : value2
Parameter key : name1
Parameter value : value1
I have deployed my app in App Engine using maven (https://cloud.google.com/appengine/docs/flexible/java/using-maven)
How can I programmatically get the URL of the APP?
I know it follows this format https://PROJECT_ID.REGION_ID.r.appspot.com. However, I do not know the region Id. If there is no way to get the URL, is there a way to get the region ID?
edit
I found this to be useful for this purpose:
https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps/get
This command will get the URL of the deployed App Engine:
gcloud app browse
I'm using this code on my production env to identify the URL. Getting of REGIONID dynamically using code is not possible for now. At least in my current SDK it is not available. Someday they will do that.
For now REGIONID.r is not mandatory in the URL as per the Google documentation. It might be required in future projects. This code will work for you.
https://cloud.google.com/appengine/docs/standard/python/how-requests-are-routed#region-id
import com.google.appengine.api.modules.ModulesServiceFactory;
import com.google.appengine.api.utils.SystemProperty;
import com.google.apphosting.api.ApiProxy;
public static void main(String[] args) {
String projectId = ApiProxy.getCurrentEnvironment().getAppId().indexOf("~")>-1?
ApiProxy.getCurrentEnvironment().getAppId().split("~")[1]:ApiProxy.getCurrentEnvironment().getAppId();
ModulesService ssf = ModulesServiceFactory.getModulesService();
String url = null;
if(SystemProperty.environment.value()!=SystemProperty.Environment.Value.Production) {
url = "http://localhost:PORT_NUMBER";
}
if(ssf.getDefaultVersion(ssf.getCurrentModule()).equals(ssf.getCurrentVersion())) {
//This is default version
url = "https://" + projectId + ".appspot.com";
}
//The URL with the current version ID
url = "https://" + ssf.getCurrentVersion() + "-dot-" + projectId + ".appspot.com";
//The URL with the module name, current version name
url = "https://" + ssf.getCurrentVersion() + "-dot-" + ssf.getCurrentModule() + "-dot-" + projectId + ".appspot.com";
}
I am writing a java rest module, with jersey 2, whose first step is to get user credentials from an external Oauth2 server. When I try to redirect the user to the authentications service I see that url is correctly generated but It stays in the place. This is the code i am executing:
#GET
public String inOk(
#DefaultValue("") #QueryParam("code") String inoauthcode)
{
String oauthserv = "https://xxx";
String oauthclientid = "xxx";
String oauthsecret = "xxxx";
String oauthredirect = "http://myapp/url";
String oauthurl = "xxxx";
String redurl = "http";
String authurl = "http";
if (inoauthcode.equals("")) {
redurl = oauthserv + "?response_type=code&client_id=" + oauthclientid + "&redirect_uri=" + oauthredirect;
URI uri = UriBuilder.fromUri(redurl).build();
Response.temporaryRedirect(uri);
}
authurl = oauthurl + inoauthcode + "&redirect_uri=" + oauthredirect + "&client_id=" + oauthclientid + "&client_secret=" + oauthsecret;
...REST OF CODE ...
}
If I write the generated url to the screen It works perfectly but the temporaryRedirect command is doing nothing (aparently).
What am I doing wrong? Did I forget something? This code is almost directly copied from similar questions asked in this forum, but I can't get it to work.
It was an easy one this time, but took long to figure out.
The output of the function should not be a String but a Response:
public String inOk(
The redirection command should look like this:
return Response.seeOther(uri).build();
And now it works.
I'm trying to pull a list of contacts from a google account. But Google returns a 401.
The url used for requesting an authorization code:
String codeUrl = 'https://accounts.google.com/o/oauth2/auth' + '?'
+ 'client_id=' + EncodingUtil.urlEncode(CLIENT_ID, 'UTF-8')
+ '&redirect_uri=' + EncodingUtil.urlEncode(MY_URL, 'UTF-8')
+ '&scope=' + EncodingUtil.urlEncode('https://www.google.com/m8/feeds/', 'UTF-8')
+ '&access_type=' + 'offline'
+ '&response_type=' + EncodingUtil.urlEncode('code', 'UTF-8')
+ '&approval_prompt=' + EncodingUtil.urlEncode('force', 'UTF-8');
Exchanging the returned authorization code for an access token (and refresh token):
String params = 'code=' + EncodingUtil.urlEncode(authCode, 'UTF-8')
+ '&client_id=' + EncodingUtil.urlEncode(CLIENT_ID, 'UTF-8')
+ '&client_secret=' + EncodingUtil.urlEncode(CLIENT_SECRET, 'UTF-8')
+ '&redirect_uri=' + EncodingUtil.urlEncode(MY_URL, 'UTF-8')
+ '&grant_type=' + EncodingUtil.urlEncode('authorization_code', 'UTF-8');
Http con = new Http();
Httprequest req = new Httprequest();
req.setEndpoint('https://accounts.google.com/o/oauth2/token');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setBody(params);
req.setMethod('POST');
Httpresponse reply = con.send(req);
Which returns a JSON array with what looks like a valid access token:
{
"access_token" : "{access_token}",
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : "{refresh_token}"
}
However when I try and use the access token (either in code or curl) Google returns a 401:
curl -H "Authorization: Bearer {access_token}" https://www.google.com/m8/feeds/contacts/default/full/
Incidentally the same curl command but with an access token acquired via https://code.google.com/oauthplayground/ works. Which leads me to believe there is something wrong with the exchanging authorization code for access token request as the returned access token does not work.
I should add this is all within the expires_in time frame so its not that the access_token has expired
Ok so the problem was in the scope when requesting an authorization code. I had accidentally set the scope to be https://www.google.com/m8/feeds/contacts/default/full (the url for retrieving all contacts), the perils of late night coding. Ironically as the example in the question used the correct hard coded url it did not have the error. I'll leave the question in the hope that those having a similar problem will find it and the code in the question works.
How do you get the source domain using HttpServletRequest?
Source domain is the requester's domain.
Thanks.
You could do either
// gets client (browser)'s hostname
String host = request.getRemoteHost();
OR
// get the server's domain name.
String domain = new URL(request.getRequestURL().toString()).getHost();
To get the source domain you can use request.getHeader("origin")
especially if the requests have to pass through a proxy server.
Hostname request
InetAddress ip = InetAddress.getLocalHost();
String hostname = ip.getHostName();
out.print("Your current IP address : " + ip+"\n");
out.print("Your current Hostname : " + hostname);