How to pass parameters to components rendered offline? - java

I have MyComponent:
public class MyComponent
{
#Parameter(required = false)
#Property
private String testParameter;
}
And I render it offline with the following code:
PageRenderRequestParameters pageRenderRequestParameters = new PageRenderRequestParameters(
"mycomponent", new ArrayEventContext(this.typeCoercer, ""), false);
StringWriter stringWriter = new StringWriter();
try
{
this.offlineComponentRenderer.renderPage(stringWriter,
new DefaultOfflineRequestContext(), pageRenderRequestParameters);
} catch (IOException e)
{
e.printStackTrace();
}
String htmlOutput = stringWriter.toString();
I don't know how to set the testParameter of MyComponent to imitate the following call:
<t:mycomponent testParameter="something" />

I think you failed to mention that you're using tapestry-offline, a 3rd party tapestry library.
You will need to create a page which includes the component before it can be rendered. If you want to make the parameter configurable, you will probably bind the property to the page activation context
Note: If you don't want the page to be visible on your website, you could probably annotate it with WhitelistAccessOnly and tweak the offline request so that it is whitelisted.

Related

change (or set ) encoding web service

I have a web service using JAX-WS API (a soap web service).
import javax.jws.WebService;
#WebService
public class Accounts {
public String getFullName(String userID){
AccountManager GFN = new AccountManager();
return GFN.getFullName(userID);
}
what can I do to change it's encoding to "UTF-8" (for non-English character)?
I fount something like "#Produces("text/html; charset=UTF-8")" but it is for JAX-RS (restful web service) i need something for JAX-WS.
Thanks.
To start, you need to get a hold of the SOAP message as early as possible. The best place to start is a javax.xml.ws.handler.LogicalHandler (as opposed to the more common type of handler, SOAPHandler).
The LogicalHandler intercepts the SOAP payload before the SOAPHandler, so it's the ideal place to do this
Within this handler, you have the liberty to whatever you want with the message, long before the encoding becomes a problem. Your code should look something like this
public class YourHandler implements LogicalHandler{
public boolean handleMessage(LogicalMessageContext context) {
boolean inboundProperty= (boolean)context.get(MessageContext.MESSAGE_INBOUND_PROPERTY);
if (inboundProperty) {
LogicalMessage lm = context.getMessage();
Source payload = lm.getPayload();
Source recodedPayload = modifyEncoding(payload); //This is where you change the encoding. We'll talk more about this
lm.setPayload(recodedPayload) //remember to stuff the payload back in there, otherwise your change will not be registered
}
return true;
}
}
So now you have the message. How to handle the change of encoding can be tricky, but it's completely up to you.
You have the option of setting the encoding on the entire message, or navigating (with xpath) to the field you're interested in and manipulating just that. Even for those two options, there are several ways of accomplishing both. I'm going to go the lazy route: set the encoding on the entire payload:
private Source modifyEncoding(Source payload){
StringWriter sw = new StringWriter();
StreamSource newSource = null;
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //this determines the outcome of the transformation
StreamResult output = new StreamResult(sw);
transformer.transform(source, output);
StringReader sReader = new StringReader(sw.toString());
newSource = new StreamSource(sReader);//Stuff the re-encoded xml back in a Source
} catch(Exception e){
ex.printStackTrace();
}
return newSource;
}
After the LogicalHandler, you now have the SOAPHandler. Here, setting the encoding is more straightforward, but its behaviour is implementation-dependent. Your SOAPHandler can look like this:
public class YourSOAPHandler implements SOAPHandler{
public boolean handleMessage(SOAPMessageContext msgCtxt){
boolean inbound = (boolean)msgCtxt.get(MessageContext.MESSAGE_INBOUND_PROPERTY);
if (inbound){
SOAPMessage msg = msgCtxt.getMessage();
msg.setProperty(javax.xml.soap.SOAPMessage.CHARACTER_SET_ENCODING,"UTF-8");
msgCtxt.Message(msg); //always put the message back where you found it.
}
}
return true;
}

GeoTools WebMapServer GetMapRequest issue

I'm using GeoTools 12.2 for developing java class library project.
Firstly, I'm working on GeoTools WMS module with this guide.
The point that I was failed is doing get map request so that I could get capabilities document and layers etc.
My wms url http://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer
It contains 3 layers (States,Rivers,Cities)
I'm using structure to get map operation like below.
GetMapRequest getMapRequest = wms.createGetMapRequest();//wms is my WebMapServer object
getMapRequest.addLayer(tempLayer);//tempLayer contains states layer
GetMapResponse response = (GetMapResponse) wms.issueRequest(getMapRequest);
BufferedImage image = ImageIO.read(response.getInputStream());
I also tried other methods in guide to do GetMapRequest but I can't succeed, always getting NullPointerException to BufferedImage object.
What is your suggestions? Thanks in advance.
You need to set some more parameters for your request, the WMS getMapResponse doesn't provide any defaults for several of them (as they are unique to your request/map). So you need at least the following:
private BufferedImage getLayer(Layer l) {
GetMapRequest getMapRequest = wms.createGetMapRequest();
getMapRequest.addLayer(l);
getMapRequest.setBBox(l.getEnvelope(DefaultGeographicCRS.WGS84));
getMapRequest.setDimensions(200, 400);
getMapRequest.setFormat("image/png");
getMapRequest.setSRS("CRS:84");
System.out.println(getMapRequest.getFinalURL());
try {
GetMapResponse response = wms.issueRequest(getMapRequest);
BufferedImage image = ImageIO.read(response.getInputStream());
return image;
} catch (ServiceException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
In general to avoid getting an empty image you can do some error checking on the response:
if (response.getContentType().equalsIgnoreCase("image/png")) {
BufferedImage image = ImageIO.read(response.getInputStream());
return image;
} else {
StringWriter writer = new StringWriter();
IOUtils.copy(response.getInputStream(), writer);
String error = writer.toString();
System.out.println(error);
return null;
}
which will give you an XML encoded error to tell you what went wrong:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<ServiceExceptionReport version="1.3.0"
xmlns="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
<ServiceException code="InvalidFormat">
Parameter 'bbox' can not be empty.
</ServiceException>
</ServiceExceptionReport>

PayPal REST API java sdk - custom config file

Good afternoon all!
I use PayPal REST API java sdk and I want to have different configurations for different environments of my application. Here is how I'm trying to do so:
private static boolean IS_PRODUCTION = false;
private static String PAYPAL_ACCESS_TOKEN;
private static void initPayPal() {
InputStream is = null;
try {
is = ApplicationConfig.class.getResourceAsStream(
IS_PRODUCTION? "/my_paypal_sdk_config.properties" : "/my_paypal_sdk_config_test.properties");
PayPalResource.initConfig(is);
String clientID = ConfigManager.getInstance().getConfigurationMap().get("clientID");
String clientSecret = ConfigManager.getInstance().getConfigurationMap().get("clientSecret");
PAYPAL_ACCESS_TOKEN = new OAuthTokenCredential(clientID, clientSecret).getAccessToken();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(is);
}
}
and while trying to get the clientID I have
java.io.IOException: Resource 'sdk_config.properties' could not be found
Strange behavior - I thought I've just configured the sdk to use my own properties file.
Please advice how could I set up those settings properly!
So here is the solution I found:
Create an empty sdk_config.properties file in default location
Load your own properties:
private static void initPayPal() {
InputStream is = null;
try {
is = ApplicationConfig.class.getResourceAsStream(
IS_PRODUCTION ? "/my_paypal_sdk_config.properties" : "/my_paypal_sdk_config_test.properties");
Properties props = new Properties();
props.load(is);
PayPalResource.initConfig(props);
ConfigManager.getInstance().load(props);
String clientID = ConfigManager.getInstance().getConfigurationMap().get("clientID");
String clientSecret = ConfigManager.getInstance().getConfigurationMap().get("clientSecret");
PAYPAL_ACCESS_TOKEN = new OAuthTokenCredential(clientID, clientSecret).getAccessToken();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
IOUtils.closeQuietly(is);
}
}
We have made some good improvements to the PayPal Java SDK on integration steps. We are removing the need for sdk_config.properties file as they do not work as well, specially for multi-configuration settings.
Now, all you do is create an APIContext instance with clientId, clientSecret, and mode. You pass that context object for any API operation from there on.
Here is how the code would look like for different configurations:
APIContext defaultContext = new APIContext(clientId1, clientSecret1, "sandbox");
APIContext sandboxContext = new APIContext(clientId2, clientSecret2, "sandbox");
APIContext someOtherContext = new APIContext(clientId3, clientSecret3, "live");
APIContext liveContext = new APIContext(clientId, clientSecret, "live");
// Now pass any of the above context in these calls, and it would use those configurations.
Payment payment = new Payment();
// Fill in all the details.
payment.create(defaultContext);
// Replace that defaultContext with any of those other contexts.
Here is the wiki page explaining that: https://github.com/paypal/PayPal-Java-SDK/wiki/Making-First-Call
I had the same error with SDK 0.11 version. I use my own properties file, but code still looked for "sdk_config.properties". I put it into root in my CLASSPATH, but still got the same error. Then I made obvious and horrible solution: put empty "sdk_config.properties" into "rest-api-sdk-0.11.0.jar" library. This street magic solved my problem.

Resolving protected resources with Flying Saucer (ITextRenderer)

I'm using Flying Saucer to create a pdf from xhtml, hosted on a tomcat server. Most of the images included in the pdf are publicly available (logos and so on), but some of them are protected behind a login (that is, they are streamed through a servlet if the user is logged in).
When I paste the url in the browser, the image is of course displayed fine, because the browser sends the session with the request. But when Flying Saucer renders the pdf, it doesn't include the protected image because it doesn't know anything about the session.
So, my question is; is there any way to include the byte streams for Flying Saucer to resolve, just as it is possible to add resolvable fonts? I have tried something like this, but there is no easy way to set the UAC on the ITextRenderer, and it complained every time i tried.
You can set the UserAgentCallback this way, and Flying Saucer will use it to resolve the urls (tested, works with Release 8):
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setUserAgentCallback(new MyUAC());
MyUAC should extend the NaiveUserAgent, and override the resolveAndOpenStream method as the other page suggests.
I overrode ITextUserAgent as well - from the source, looks like that's what ITextRenderer uses. You have to provide the output device in the constructor, which you can get from the renderer object. One other gotcha was you have to set the "shared context" explicitly using the setter method - otherwise you will get an NPE during rendering. Here is the code to set up the object:
ITextRenderer renderer = new ITextRenderer();
MyUserAgentCallback uac = new MyUserAgentCallback(renderer.getOutputDevice());
uac.setSharedContext(renderer.getSharedContext());
renderer.getSharedContext().setUserAgentCallback(uac);
Also, here is the basic idea of MyUserAgentCallback, using basic authentication:
private static class MyUserAgentCallback extends ITextUserAgent
{
public MyUserAgentCallback(ITextOutputDevice outputDevice)
{
super(outputDevice);
}
#Override
protected InputStream resolveAndOpenStream(String uri)
{
if (_isProtectedResource(uri))
{
java.io.InputStream is = null;
uri = resolveURI(uri);
try {
URL url = new URL(uri);
String encoding = new BASE64Encoder().encode ("username:password".getBytes());
URLConnection uc = url.openConnection();
uc.setRequestProperty ("Authorization", "Basic " + encoding);
is = uc.getInputStream();
Log.debug("got input stream");
}
catch (java.net.MalformedURLException e) {
Log.error("bad URL given: " + uri, e);
}
catch (java.io.FileNotFoundException e) {
Log.error("item at URI " + uri + " not found");
}
catch (java.io.IOException e) {
Log.error("IO problem for " + uri, e);
}
return is;
}
else
{
return super.resolveAndOpenStream(uri);
}
}
private boolean _isProtectedResource(String uri)
{
// does this require authentication?
}
}

using freemarker and spring to construct templates

I am new to freemarker. I have a spring application that I am planning to use with freemarker. Templates will be stored in database and based on the login, I want to retrieve the template from database. Can any one tell me how to configure the freemarker in spring and get the html tags as a string after constructing the template. I did googling but I could not understand much.
I tried till this level. In spring I have done till this level. Finally I want html tags in a string.
// Spring freemarker specific code
Configuration configuration = freemarkerConfig.getConfiguration();
StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
// My application specific code
String temp = tempLoader.getTemplateForCurrentLogin();
Thanks.
To tie together the bits of code you posted, you can do something like this:
// you already have this bit
String templateText = tempLoader.getTemplateForCurrentLogin();
// now programmatically instantiate a template
Template t = new Template("t", new StringReader(templateText), new Configuration());
// now use the Spring utility class to process it into a string
// myData is your data model
String output = FreeMarkerTemplateUtils.processTemplateIntoString(template, myData);
This java method will process the freemarker template and will give html tags as String after constructing the template.
public static String processFreemarkerTemplate(String fileName) {
StringWriter stringWriter = new StringWriter();
Map<String, Object> objectMap = new HashMap<>();
Configuration cfg = new Configuration(Configuration.VERSION_2_3_24);
try {
cfg.setDirectoryForTemplateLoading(new File("path/of/freemarker/template"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
Template template = cfg.getTemplate(fileName);
template.process(objectMap, stringWriter);
} catch (IOException | TemplateException e) {
e.printStackTrace();
} finally {
if (stringWriter != null) {
try {
stringWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringWriter.toString();
}

Categories