Is it possible to get the absolute request url without path parameters - java

I am trying to get the request url without values of path parameters into it.
Consider my complete url is
URl: http://localhost:8080/aaa/mock/abcd/1234/true
Path parameters: abcd, true
Output needed: /aaa/mock/abcd
My web service method looks like this.
#Path(value = "/aaa/mock")
#Component
public class MockService
{
private static Log log = LogFactory.getLog(MockService.class);
//address
#GET
#Path(value = "/{mockrequest}/{status}")
#Produces(MediaType.JSON)
public String mockEngagement(#Context ContainerRequestContext request,#PathParam("mockrequest") String mockrequest,#PathParam("status") String status )
{
log.info("The mock url is"+request.getUriInfo().getRequestUri());
log.info("The mock url is"+request.getUriInfo().getAbsolutePath());
log.info("The mock url is"+request.getUriInfo().getBaseUri());
log.info("The mock url is"+request.getUriInfo().getMatchedURIs());
**//Out put needed /aaa/mock/abcd**
return "ajaja";
}
}
None of the above calls return the required info.
I am thinking if there is a generic process to get the desired output irrespective of number of path parameters.
Any such methods.

Try UriInfo#getPath(), UriInfo#getPath(boolean), or UriInfo#getPathSegments(). The boolean argument is whether the path should be encoded or not.
https://jersey.java.net/apidocs/2.3.1/jersey/index.html
You could also get the absolute path and the base path and then use URI#relativize(URI).

Try this:
request.getUriInfo().getPathSegments().get(0).getPath()

public void filter(ContainerRequestContext context) throws IOException {
Message message = PhaseInterceptorChain.getCurrentMessage();
Set<Map.Entry<String, Object>> o = (Set<Map.Entry<String, Object>>)message.entrySet();
for (Map.Entry<String, Object> oo : o) {
String key = oo.getKey();
Object val = oo.getValue();
// Thises two properties gives the path of web service
//path_to_match_slash
//org.apache.cxf.request.uri
if(key.equals("path_to_match_slash"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
if(key.equals("org.apache.cxf.request.uri"))
{ String v = (String)val;
System.out.println (key);
System.out.println (v);
}
}
}
this code could work only for apache cxf rest
we can found path_to_match_slash , org.apache.cxf.request.uri properties in the ContainerRequestContext

Related

How to load quarkus qute template dynamic without inject?

I had the following problem: I have a service where I want to dynamically render templates using qute. Whose names I don't currently know (because they are passed via the endpoint).
Unfortunately Quarkus itself doesn't give the possibility to say "Template t = new Template()".... You always have to define them via inject at the beginning of a class. After a long time of searching and thinking about it, I have the following solution:
The solution is to inject the Quarkus Template Engine instead of a Template. The Engine could render a template directly.... Then we only have to read our template file as a String (Java 11 can read Files.readString(path, encoding)) and render it with our data map.
#Path("/api")
public class YourResource {
public static final String TEMPLATE_DIR = "/templates/";
#Inject
Engine engine;
#POST
public String loadTemplateDynamically(String locale, String templateName, Map<String, String> data) {
File currTemplate = new File(YourResource.class.getResource("/").getPath() + TEMPLATE_DIR + locale + "/" + templateName + ".html"); // this generates a String like <yourResources Folder> + /templates/<locale>/<templateName>.html
try {
Template t = engine.parse(Files.readString(currTemplate.getAbsoluteFile().toPath(), StandardCharsets.UTF_8));
//this render your data to the template... you also could specify it
return t.data(data.render());
} catch (IOException e) {
e.printStackTrace();
}
return "template not exists";
}
}

Java Use URI builder?

I have bellow url :
http://www.example.com/api/Video/GetListMusicRelated/0/0/null/105358/0/0/10/null/null
This section is Fixed and unchangeable:
http://www.example.com/api/Video/GetListMusicRelated/
I set parameter to this url like bellow :
http://www.example.com/api/Video/GetListMusicRelated/25/60/jim/105358/20/1/5/null/null
OR :
http://www.example.com/api/Video/GetListMusicRelated/0/0/null/105358,5875,85547/0/0/10/null/null
How I can write for this url a url builder ?
If you want to create an UrlBuilder using the builder pattern, it could be done like this:
public class UrlBuilder {
private final String root;
private int myParam1;
private String myParam2;
public UrlBuilder(final String root) {
this.root = root;
}
public UrlBuilder myParam1(int myParam1) {
this.myParam1 = myParam1;
return this;
}
public UrlBuilder myParam2(String myParam2) {
this.myParam2 = myParam2;
return this;
}
public URL build() throws MalformedURLException {
return new URL(
String.format("%s/%d/%s", root, myParam1, myParam2)
);
}
}
Then you will be able to create your URL as next
URL url = new UrlBuilder("http://www.example.com/api/Video/GetListMusicRelated")
.myParam1(25)
.myParam2("jim")
.build();
NB: This only shows the idea, so I used fake parameter's name and incorrect number of parameters, please note that you are supposed to have 6 parameters and set the proper names.
try this...
URL domain = new URL("http://example.com");
URL url = new URL(domain + "/abcd/abcd");

Java & Apache-Camel: From direct-endpoint to file-endpoint

I've tried to build a route to copy files from one directory to an other directory. But instead of using:
from(file://source-directory).to(file://destination-directory)
I want to do something like this:
from(direct:start)
.to(direct:doStuff)
.to(direct:readDirectory)
.to(file://destination-folder)
I've done the following stuff:
Route
#Component
public class Route extends AbstractRouteBuilder {
#Override
public void configure() throws Exception {
from("direct:start")
.bean(lookup(ReadDirectory.class))
.split(body())
.setHeader("FILENAME", method(lookup(CreateFilename.class)))
.to("file:///path/to/my/output/directory/?fileName=${header.FILENAME}");
}
Processor
#Component
public class ReadDirectory implements CamelProcessorBean {
#Handler
public ImmutableList<File> apply(#Header("SOURCE_DIR") final String sourceDir) {
final File directory = new File(sourceDir);
final File[] files = directory.listFiles();
if (files == null) {
return ImmutableList.copyOf(Lists.<File>newArrayList());
}
return ImmutableList.copyOf(files);
}
}
I can start my route by using the following pseudo-Test (The point is I can manually start my route by producer.sendBodyAndHeader(..))
public class RouteIT extends StandardIT {
#Produce
private ProducerTemplate producer;
#Test
public void testRoute() throws Exception {
final String uri = "direct:start";
producer.sendBodyAndHeaders(uri, InOut, null, header());
}
private Map<String, Object> header() {
final Map<String, Object> header = Maps.newHashMap();
header.put("SOURCE_DIR", "/path/to/my/input/directory/");
return header;
}
}
AbstractRouteBuilderextends SpringRouteBuilder
CamelProcessorBean is only a Marker-Interface
StandardIT loads SpringContext and stuff
The problem is, that I must set the filename. I've read some stuff that camel sets the header CamelFileNameProduced (during the file endpoint). It is a generic string with timestamp and if I don't set the filename - the written files will get this generic string as the filename.
My Question is: Is there a more beautiful solution to copy files (but starting with a direct-endpoint and read the directory in the middle of the route) and keep the filename for the destination? (I don't have to set the filename when I use from("file:source").to("file:destination"), why must I do it now?)
You can set the file name when you send using the producer template, as long as the header is propagated during the routing between the routes you are all fine, which Camel does by default.
For example
#Test
public void testRoute() throws Exception {
final String uri = "direct:start";
Map headers = ...
headers.put(Exchange.FILE_NAME, "myfile.txt");
producer.sendBodyAndHeaders(uri, InOut, null, headers);
}
The file component talks more about how to control the file name
http://camel.apache.org/file2

Jersey getting template path

Im using Jersey 2 and I want to get the URI template.
The reason is that Im creating an auth system that validates based on the URI. I managed to work:
#Override
public void filter(ContainerRequestContext containerRequest) throws IOException {
String method = containerRequest.getMethod();
String uri = containerRequest.getUriInfo().getPath();
}
The problem is that getPath returns something like:
/companies/1
And I want it to return
/companies/{id}
Which is how I declared with:
#Path("{id}")
thank you
EDIT I thought I found it here:
#Context
private ExtendedUriInfo uriInfo;
//...
Resource matchedModelResource = uriInfo.getMatchedModelResource();
System.out.println(matchedModelResource.getPathPattern().getTemplate().getTemplate());
buut guess what? matchedModelResource is null.
Also, this:
List<UriTemplate> matchedTemplates = uriInfo.getMatchedTemplates();
Returns an Empty List of UriTemplate. :(
Why are the data not beeing set?
Ok. So the answer is to use:
uriInfo.getMatchedTemplates();
Where uriInfo is actually ExtendedUriInfo.
This is the code I've made to get the correct syntax:
List<UriTemplate> matchedTemplates = uriInfo.getMatchedTemplates();
StringBuilder builder = new StringBuilder();
for (int i = matchedTemplates.size() - 1; i >= 0; i--) {
builder.append(matchedTemplates.get(i).getTemplate().substring(1));
}
System.out.println("Permission is: " + builder.toString());
// Prints:
// Permission is: sig/companies/{id}
The reason the data was null or empty before is because I had an #PreMatching annotation in my filter class. Please dont ask why.
Hope this helps someone.

Parsing an URL in SVNKit

I'm trying to parse an URL in order to obtain the current branch or trunk.
public SVNConnector(String s_Url, String login, String password, String project) {
try {
url = SVNURL.parseURIEncoded(s_Url);
ISVNAuthenticationManager authManager = new BasicAuthenticationManager(login, password);
DAVRepositoryFactory.setup();
repository = SVNRepositoryFactory.create(url, null);
repository.setAuthenticationManager(authManager);
this.projectName = project;
latestRevision = repository.getLatestRevision();
} catch (SVNException svne) {
logger.error("Impossible to connect to SVN repository. s_Url: "+s_Url+" login:"+login+" password: "+password, svne);
}
}
My URL is something like http://10.61.128.222/svn/i18ntest/trunk or http://10.61.128.222/svn/PFT/branches/protoi18n and I need a method where I could enter this URL and it would return /trunk/ or /branches/protoi18n/, so I could run this:
public List<OutputElement> retrieveI18nFiles() throws SVNException {
List<OutputElement> outs = new ArrayList<OutputElement>();
String path = url.getPath()+"/core/src/main/resources/fr/gefco/"+projectName+"/i18n/"; // this is not working!
latestRevision = repository.getLatestRevision();
// For some reason, type safety is not insured in SVNKit, even if generics are around for some years, now
Collection<SVNDirEntry> entries = repository.getDir(path, latestRevision, (SVNProperties)null, (Collection<SVNDirEntry>)null);
for (SVNDirEntry entry : entries) {
OutputElement out = new OutputElement();
out.setEntry(entry);
out.setOut(retrieveOutputStream(entry,path));
outs.add(out);
}
return outs;
}
url.getPath() is returning /svn/i18ntest/trunk/, which is not what I need. Of course, I could parse it to get the bit I need, but I would like to know first if SVNKit provides any already proven way to do that.
When working with SVNRepository you need paths relative to the repository root. You may retrieve the repository root URL using SVNURL root = repository.getRepositoryRoot(true) and then use SVNURLUtil.getRelativeURL(root, url, false) to get the relative path between your url and the repository root URL.

Categories