How do I read a JNDI property from a Client GWT app - java

On Server side, there is a JNDI resource, that I need to read from a Client GWT App.
I know, that I can make a GWT RPC call to get the JNDI resource dynamically, but the JNDI resource is a static URL, that will not change, once the page is loaded. So - my idea was to load the JNDI resource when loading the page.
I found an outdated description about how this could be done - in 2011
https://webtide.com/gwt-and-jndi/
However, I would like to know, whether this would be possible for a more current version of GWT (I am using GWT 2.7.0)

I had the same problem. Pass JNDI parameters and some other configuration values to the GWT application.
The trick is to generate the GWT hostpage dynamically (with JSP in my case).
Each inital call to my GWT application goes to a front controller (a Servlet) for authorizition purposes and some other intitialization stuff.
Then I get all the JNDI parameters and other values, put them into the request context and call the hostpage JSP.
In my JSP page I define a JavaScript hash and initialize it with the parameters.
<script type="text/javascript">
var my_params = {
jndiParam1: '<%= request.getAttribute("jndiParam1") %>',
exampleUrl: '<%= request.getAttribute("exampleUrl") %>',
jndiParam2: '<%= request.getAttribute("jndiParam2") %>'
};
</script>
And inside my GWT application I have a class HostPageParameter which uses a com.google.gwt.i18n.client.Dictionary to access the JavaScript hash my_params.
public class HostPageParameter {
private static final String DICTNAME = "my_params";
private static HostPageParameter instance = null;
public static HostPageParameter getInstance() {
if(instance == null) {
instance = new HostPageParameter();
}
return instance;
}
private Dictionary myParams;
private HostPageParameter() {
try {
myParams = Dictionary.getDictionary(DICTNAME);
} catch(MissingResourceException e) {
// If not defined
myParams = null;
}
}
public String getParameter(String paramName) {
return getParameter(paramName, null);
}
public String getParameter(String paramName, String defaultValue) {
String paramValue = null;
if(myParams != null && paramName != null) {
try {
paramValue = myParams.get(paramName);
} catch (MissingResourceException e) {
// If not defined
paramValue = defaultValue;
}
}
return paramValue;
}
}
And to read the values you simply can use:
// Without a default value, If not defined, null is returned.
final String jndiParam1 = HostPageParameter.getInstance().getParameter("jndiParam1");
// With default value.
final String exampleUrl = HostPageParameter.getInstance().getParameter("exampleUrl",
"http://example.com");

Related

apache-cfx and JAXRSx log with the wrong ressourceName

I use Spring and jaxrs
I have a restApi with 2 endpoints, say
/cats
/dogs
each endpoint is in its own ressource class, say CatRessource.class and DogRessource.class
everythings works fine, but the ressourceName in the apache-cfx logging is wrong, i always end-up with a componentId :
org.apache.cxf.services.CatRessource.REQ_IN -
even if I know, my code is going the the DogRessource class.
from what I looked, the name come from apache
protected Logger getLogger(final LogEvent event) {
final String cat = "org.apache.cxf.services." + event.getPortTypeName().getLocalPart() + "." + event.getType();
return LoggerFactory.getLogger(cat);
}
who gets it from
Endpoint ep = message.getExchange().getEndpoint()
and looking still up, that endpoint is created when the APi start, the name of the ressource is given by Jaxrs who gives the name of the first ressourceclass it finds
public class JAXRSServiceImpl extends AbstractAttributedInterceptorProvider implements Service, Configurable {
...
public QName getName() {
if (serviceName != null) {
return serviceName;
}
if (address == null && !classResourceInfos.isEmpty()) {
Class<?> primaryClass = classResourceInfos.get(0).getServiceClass();
String ns = PackageUtils.getNamespace(PackageUtils.getPackageName(primaryClass));
return new QName(ns, primaryClass.getSimpleName());
}
return new QName(address, "WebClient");
}
is there an easy way to have the correct name in the log, or a default one?

Unable to get data from java web service

Someone please help me i keep trying but not able to find out why i am unable to get the results.
I have created this java springboot web service where when I run the java application, a web browser page will open and when I type in the URL e.g localhost:8080/runbatchfileparam/test.bat the program will check if the test.bat file exist first. If it does, the web page will show a JSON result {“Result”: true} and the command in the batch file will be executed. If it does not exist, the web page will show {“Result”: false}.
I want to create an ASP.NET Web Service that will use the function created in the java web service. When I run the ASP.NET Web Application, a web browser page will open. User will type in URL something like this: localhost:12345/api/callbatchfile/test.bat. The java web service should be running and I should get either {“Result”: true} or {“Result”: false} when I run the C# ASP.NET Web Application too.
However I only get an empty {} without anything inside the brackets. Why is that so?
Here are my code in ASP.NET
TestController.cs
private TestClient testClient = new TestClient();
public async Task<IHttpActionResult> GET(string fileName)
{
try
{
var result = await testClient.runbatchfile(fileName);
var resultDTO = JsonConvert.DeserializeObject<TestVariable>(result);
return Json(resultDTO);
}
catch (Exception e)
{
var result = "Server is not running";
return Ok(new { ErrorMessage = result });
}
}
TestVariable.cs
public class TestVariable
{
public static int fileName { get; set; }
}
TestClient.cs
private static HttpClient client;
private static string BASE_URL = "http://localhost:8080/";
static TestClient()
{
client = new HttpClient();
client.BaseAddress = new Uri(BASE_URL);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> runbatchfile(string fileName)
{
var endpoint = string.Format("runbatchfile/{0}", fileName);
var response = await client.GetAsync(endpoint);
return await response.Content.ReadAsStringAsync();
}
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "TestBatchClient",
routeTemplate: "api/runbatchfile/{fileName}",
defaults: new { action = "GET", controller = "Test" }
);
Someone please do help me. Thank you so much.
EDIT
Java web service
Application.java
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
BatchFileController.java
private static final String template = "Sum, %s!";
#RequestMapping("/runbatchfile/{param:.+}")
public ResultFormat runbatchFile(#PathVariable("param") String fileName) {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch(fileName);
}
ResultFormat
private boolean result;
public ResultFormat(boolean result) {
this.result = result;
}
public boolean getResult() {
return result;
}
RunBatchFile.java
public ResultFormat runBatch(String fileName) {
String var = fileName;
String filePath = ("C:/Users/attsuap1/Desktop/" + var);
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return new ResultFormat(exitVal == 0);
} catch (Exception e) {
e.printStackTrace();
return new ResultFormat(false);
}
}
I am not sure if this helps.. but I suspect that the AsyncTask is not really executing...
var result = await testClient.testCallBatchProject(fileName);
I would try something like below:
await testClient.testCallBatchProject(fileName).Delay(1000);
Can you try and check if the same happens for a synchronous call? .. if it does, we can zero down on the above.

Explicitly Logout the User programmatically in Websphere Portal 8 & redirect to the default login page

I am a bit new to WS portal & have a requirement wherein on a specific scenario we want the user to logout & redirect him to the default portal login page.
I have tried to invalidate the session clear the cookies & do a response.sendRedirect as in response.sendRedirect("/wps/myportal/"); ,
but in vain.
Please guide.
You can configure logout page using wp_configservice:
redirect.logout=true
redirect.logout.ssl=false
redirect.logout.url=protocol://host_name/logout_page
After configuring it, clicking on standard logout will redirect you to the specified page.
If you're using JSF portlets, you can do something along the lines of the following - this should actually log the user session out as well as returning them to the default login page.
In reality you'll probably want to consider caching the initial context lookup by moving out the lookup code ( Context ctx = new InitialContext();
PortletServiceHome stateMgrServiceHome = (PortletServiceHome) ctx.lookup("portletservice/com.ibm.portal.state.service.PortletStateManagerService");)
public void doLogOut()
{
String logoutUrl = generateLogoutURL(getPortletRequest(), getPortletResponse());
redirectToUrl(logoutUrl);
}
public String generateLogoutURL(PortletRequest request, PortletResponse response) throws RpmPortalException {
final String methodName = "generateLogoutURL";
String logoutURL = "";
Context ctx = new InitialContext();
PortletServiceHome stateMgrServiceHome = (PortletServiceHome) ctx.lookup("portletservice/com.ibm.portal.state.service.PortletStateManagerService");
PortletStateManager stateMgr = null;
LogoutActionAccessorController logoutCtrl = null;
try {
stateMgr = stateMgrService.getPortletStateManager(request, response);
final URLFactory urlFactory = stateMgr.getURLFactory();
EngineURL url = urlFactory.newURL(null);
LogoutActionAccessorFactory logoutFct = (LogoutActionAccessorFactory) stateMgr.getAccessorFactory(LogoutActionAccessorFactory.class);
logoutCtrl = logoutFct.newLogoutActionController(url.getState());
logoutURL = url.writeDispose(new StringWriter()).toString();
} catch (StateException e) {
//do whatever you want
} catch (IOException e) {
//do whatever you want
} finally {
if (stateMgr != null) {
stateMgr.dispose();
}
if (logoutCtrl != null) {
logoutCtrl.dispose();
}
}
return logoutURL;
}
public void redirectToUrl(String url) {
try {
FacesContext context = getFacesContext();
if (context != null) {
context.getExternalContext().redirect(url);
context.responseComplete();
}
} catch (IOException e) {
//Do whatever you want
}
}
In the standard configuration of Portal, directing a user to any page with /wps/portal... as the root instead of /wps/myportal/... will force the user to log out and the session to end. So you could just create a friendly URL for your login page and redirect the user to /wps/portal/friendlyLoginUrl
Just an addition to what zargarf said, by default the following js is executed when you click on logout is mentioned below :
javascript:if(stproxy && stproxy.isLoggedIn){stproxy.login.logout();}

Custom Annotation JSF

I wanted to make a custom annotation to check security on some functions for my JSF web application. For security I use Tomcat security with JaaS, so I have no application managed security to my disposal.
What actually want to do is make an annotation for my methods in the Backing Beans like Spring Security (#Secured("role")). My security system is implemented so that every function is a role and you can dynamically make "user roles" these are stored in the DB and when somebody logs in all the (function)roles in that "user role" will be set in tomcat security as roles.
So now I have this piece of code to check if my user can access the function:
public static void checkSecurity(final String function) {
final FacesContext facesContext = FacesContext.getCurrentInstance();
try {
if (facesContext.getExternalContext().getRemoteUser() == null) {
facesContext.getExternalContext().redirect("login.xhtml");
return;
}
if (!facesContext.getExternalContext().isUserInRole(function)) {
facesContext.getExternalContext().redirect("restricted.xhtml");
return;
}
} catch (final Exception ex /* Mandatory "IOException e" will be caught + all other exceptions. */) {
facesContext.getExternalContext().setResponseStatus(403); // HTTP Status 403: Forbidden. Can also throw 401.
facesContext.responseComplete();
}
}
Now I have to call this SecurityUtil.checkSecurity("name_of_function"); in every method.
But I want to have an annotation like this #CustomSecurity("function_name_role").
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface CustomSecurity {
// Single Element called value.
String value();
}
And when a method has this annotation the checkSecurity function automatically has to be performed. So I have to scan for this annotation at a point, or make some kind of actionlistener. JSF should have some options for this but all the forums I found on this don't really help.
Does somebody has some ideas?
EDIT:
I tried this blog it works but only on an action of a component (and components don't render when you don't have the role). So how secure is this when people try to hack into the JSF structure. And I rather have it running on every method.
public class SecurityActionListener extends ActionListenerImpl implements ActionListener {
private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger();
#SuppressWarnings("unused")
#Override
public void processAction(final ActionEvent event) {
final FacesContext context = FacesContext.getCurrentInstance();
final Application application = context.getApplication();
final ConfigurableNavigationHandler navHandler = (ConfigurableNavigationHandler) application.getNavigationHandler();
// Action stuff
final UIComponent source = event.getComponent();
final ActionSource actionSource = (ActionSource) source;
MethodBinding binding;
binding = actionSource.getAction();
final String expr = binding.getExpressionString();
if (!expr.startsWith("#")) {
super.processAction(event);
return;
}
final int idx = expr.indexOf('.');
final String target = expr.substring(0, idx).substring(2);
final String t = expr.substring(idx + 1);
final String method = t.substring(0, (t.length() - 1));
final MethodExpression expression = new MethodExpressionMethodBindingAdapter(binding);
final ELContext elContext = context.getELContext();
final ExpressionFactory factory = context.getApplication().getExpressionFactory();
final ValueExpression ve = factory.createValueExpression(elContext, "#{" + target + '}', Object.class);
final Object result = ve.getValue(elContext);
// Check if the target method is a secured method
// and check security accordingly
final Method[] methods = result.getClass().getMethods();
for (final Method meth : methods) {
if (meth.getName().equals(method)) {
if (meth.isAnnotationPresent(CustomSecurity.class)) {
final CustomSecurity securityAnnotation = meth.getAnnotation(CustomSecurity.class);
System.out.println("Function to check security on: " + securityAnnotation.value()); // TODO TO LOG
SecurityUtil.checkSecurity(securityAnnotation.value());
} else {
super.processAction(event);
}
break;
}
}
}
}
And this in the faces-config.xml:
<action-listener>
com.nielsr.randompackagebecauseofnda.SecurityActionListener
</action-listener>
This blog could also be an answer, but I don't know how it will work with my JaaS Tomcat security because the security is in a separate project deployed as a standalone JAR in the tomcat lib folder.
But I actually don't know that I have to secure my Beans. Because I have configured all the functions (aka roles see above) that are on 1 page in the Web.xml as security constraints. And I render the components on the page only if you have to rights or "function_role" on that component. So is this secured enough? Or if somebody has a right to a function on a page can he render the components himself and so hack my site?
I'm not that familiar to JSF to know this, what is going on in that extra JSF abstraction layer between Controller and View? (I'm more of a Spring MVC developer, but because of requirements I have to use JSF but it's nice to broaden my knowledge.)
You can "scan for your Annotations" using
http://code.google.com/p/reflections/
Regards

GWT: Capturing URL parameters in GET request

I need to build a GWT application that will be called by an external application with specific URL parameters.
For example:
http://www.somehost.com/com.app.client.Order.html?orderId=99999.
How do I capture the orderId parameter inside the GWT application?
Try,
String value = com.google.gwt.user.client.Window.Location.getParameter("orderId");
// parse the value to int
P.S. GWT can invoke native javascript which means if javascript can do the stuff, GWT can do it too; e.g. in GWT, you can write
public static native void alert(String msg)
/*-{
$wnd.alert("Hey I am javascript");
}-*/;
In this case, you can even use existing javascript lib to extract param's value in the querystring.
GWT has a facility to get params from the URL:
String value = Window.Location.getParameter("param");
Make sure your URLs are in the form of:
http://app.com/?param=value#place instead of http://app.com/#place&param=value
In order to get all params in a map, use:
Map<String, List<String>> map = Window.Location.getParameterMap();
I suggest you to use GWT MVP .
Assume that your url as
http://www.myPageName/myproject.html?#orderId:99999
And in your AppController.java --
Try as
......
public final void onValueChange(final ValueChangeEvent<String> event) {
String token = event.getValue();
if (token != null) {
String[] tokens = History.getToken().split(":");
final String token1 = tokens[0];
final String token2 = tokens.length > 1 ? tokens[1] : "";
if (token1.equals("orderId") && tonken2.length > 0) {
Long orderId = Long.parseLong(token2);
// another your operation
}
}
}
...........
Another option , you can also use with Spring MVC. Here is an example ...
// Below is in your view.java or presenter.java
Window.open(GWT.getHostPageBaseURL() + "customer/order/balance.html?&orderId=99999",
"_self", "enable");
// Below code in in your serverside controller.java
#Controller
#RequestMapping("/customer")
public class ServletController {
#RequestMapping(value = "/order/balance.html", method = RequestMethod.GET)
public void downloadAuctionWonExcel(#RequestParam(value = "orderId", required = true) final String orderId,
final HttpServletResponse res) throws Exception {
try {
System.out.println("Order Id is "+orderId);
// more of your service codes
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
You can use the Activities and Places to do that. When you create the Place for your page, you can set the orderId as a member. This member can be used afterwords when you create the Activity associated with the place (in ActivityMapper).
The only restriction is that you can't send the orderId as a normal parameter. You will have to use an url with this form :
127.0.0.1:60206/XUI.html?#TestPlace:orderId=1

Categories

Resources