Setup Fiddler as Proxy server with Basic Authentication

Fiddler can be used as a proxy server with authentication. The following steps need to be followed to set proxy credentials in Fiddler.

Set Proxy host

The machine in which the fiddler is running will be the proxy host.

Set proxy port

Goto Tools -> Fiddler Options -> Connections and set Proxy port as shown below
SetPort

Set username and password

generate base64 encoding of username password combination in the following formate. You may use TextWizard of fiddler to do the conversion.

myUser:myPasscode


where
myUser is the username and myPasscode is password. The base64 encoded content for the above combination is bXlVc2VyOm15UGFzc2NvZGU= 

Then type the following command in QuickExec command. Note that the last part in the command is the base64 encoded content prepared.

prefs set fiddler.proxy.creds bXlVc2VyOm15UGFzc2NvZGU=

QuickExec

Enable Proxy Authentication Rule in Fiddler

Set Authentication Rule

Usung TextWizard of fiddler to do base64 conversion

TextWizard

Advertisements

Capture Reqest and Response in Tomcat7

Install Logback

Download the logback distribution and  place the files logback-core-1.1.3.jar and logback-access-1.1.3.jar under $TOMCAT_HOME/lib/ directory.

Add LogbackValve

Add the below line in <Host/> tag of $TOMCAT_HOME/conf/server.xml

<Valve className="ch.qos.logback.access.tomcat.LogbackValve"/>

Add LogbackConfiguration File

Add logback-access.xml file in $TOMCAT_HOME/conf folder withr below content

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 <encoder> 
 <pattern>%fullRequest%n%n%fullResponse</pattern>
 </encoder>
 </appender>
 
 <appender-ref ref="STDOUT" />

</configuration>

Add TeeFilter

Add the below filter in $TOMCAT_HOME/conf/web.xml

<filter>
  <filter-name>TeeFilter</filter-name>
  <filter-class>ch.qos.logback.access.servlet.TeeFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>TeeFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Start tomcat in Shell

$TOMCAT_HOME/bin/catalina.sh run

Reference

http://logback.qos.ch/access.html

You can use Advanced rest client to send request to server.


Jackson for XML – JSON conversion

WebLink : http://jackson.codehaus.org/

Dependencies:

  • No External Dependencies.
  • Required components:Jackson-annotation, Jackson-core,Jackson-databind,Jackson-dataformat-xml. Jackson-dataformat-xml needs to be brought to Platform. All other components are already available in Platform.

License: The Apache Software License, Version 2.0

Advantages:

  • Faster.
  • Already being used in platform
  • actively developed library.

Disadvantages:

Example code:

xmlToJson
public static void testXMLToJSON(String xml) throws JsonParseException, JsonMappingException, IOException{
 ObjectMapper mapper = new ObjectMapper(); 
 XmlMapper xmlMapper = new XmlMapper();
 xmlMapper.setConfig(xmlMapper.getSerializationConfig().withRootName(""));
 Map<Object,Object> map = xmlMapper.readValue(xml, Map.class);
 
 String json = mapper.writeValueAsString(map);
 System.out.println(json);
 }
JsonToXml
public static void testJSONtoXML(String json) throws JsonParseException, JsonMappingException, IOException{
 ObjectMapper mapper = new ObjectMapper();
 Map<Object,Object> map = mapper.readValue(json, Map.class);
 XmlMapper xmlMapper = new XmlMapper();
 String xml = xmlMapper.writeValueAsString(map);
 System.out.println(xml);
 }

There is an issue with using java.util.Map as the java object to map xml content. It doesn’t give expected result when there is multiple elements with same tag name. This can be seen from the below samples(InputXml,ExpectedJson and ActualJson).

InputXml
		
 
 <user>
 <name>John</name>
 <age>21</age>
 <data>1</data>
 <data>2</data>
 <data>3</data>
 <data>4</data>
</user>
 

Consider the above xml, when it is converted to json, it should be converted as given in ExpectedJson.

ExpectedJson
{ 
 "user":{ 
 "name":"John",
 "age":21,
 "data":[ 1, 2, 3, 4 ]
 }
}
ActualJson
{ 
 "user":{ 
 "name":"John",
 "age":"21",
 "data":"4"
 }
}

This can be overcome by customizing the Deserialization behaviour. Basically when there is multiple value for the same key in a Map, we need to convert the value as an array.

public static void testXMLToJSON(String xml) throws JsonParseException, JsonMappingException, IOException
 {
 System.out.println(xml);
 JacksonXmlModule module = new JacksonXmlModule();
 module.setDefaultUseWrapper(false);
 XmlMapper xmlMapper = new XmlMapper();
 xmlMapper.registerModule(module);
 ObjectMapper mapper = new ObjectMapper();
 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
 Object map = xmlMapper.readValue(xml, GenericObject.class);
 String json = mapper.writeValueAsString(map);
 System.out.println(json);
 }
 
 @JsonDeserialize(using = CustomDeserializer.class)
 public class GenericObject
 {
 }
 
 public static class CustomDeserializer extends UntypedObjectDeserializer
 {
 private static final long serialVersionUID = -4628994110702279382L;
 
 protected Object mapObject(JsonParser jp, DeserializationContext ctxt) throws IOException
 {
 JsonToken t = jp.getCurrentToken();
 if (t == JsonToken.START_OBJECT)
 {
 t = jp.nextToken();
 }
 // minor optimization; let's handle 1 and 2 entry cases separately
 if (t == JsonToken.END_OBJECT)
 { // and empty one too
 // empty map might work; but caller may want to modify... so better just give small modifiable
 return new LinkedHashMap<String, Object>(2);
 }
 String field1 = jp.getCurrentName();
 jp.nextToken();
 Object value1 = deserialize(jp, ctxt);
 if (jp.nextToken() == JsonToken.END_OBJECT)
 { // single entry; but we want modifiable
 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(2);
 value1 = handleMaultipleValue(result, field1, value1);
 result.put(field1, value1);
 return result;
 }
 String field2 = jp.getCurrentName();
 jp.nextToken();
 Object value2 = deserialize(jp, ctxt);
 if (jp.nextToken() == JsonToken.END_OBJECT)
 {
 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>(4);
 value1 = handleMaultipleValue(result, field1, value1);
 result.put(field1, value1);
 value2 = handleMaultipleValue(result, field2, value2);
 result.put(field2, value2);
 return result;
 }
 // And then the general case; default map size is 16
 LinkedHashMap<String, Object> result = new LinkedHashMap<String, Object>();
 value1 = handleMaultipleValue(result, field1, value1);
 result.put(field1, value1);
 value2 = handleMaultipleValue(result, field2, value2);
 result.put(field2, value2);
 do
 {
 String fieldName = jp.getCurrentName();
 jp.nextToken();
 Object value = deserialize(jp, ctxt);
 value = handleMaultipleValue(result, fieldName, value);
 result.put(fieldName, value);
 } while (jp.nextToken() != JsonToken.END_OBJECT);
 return result;
 }
 
 @SuppressWarnings("unchecked")
 private Object handleMaultipleValue(Map<String, Object> map,
 String key,
 Object value)
 {
 if (!map.containsKey(key))
 {
 return value;
 }
 
 Object originalValue = map.get(key);
 if (originalValue instanceof List)
 {
 ((List) originalValue).add(value);
 return originalValue;
 }
 else
 {
 ArrayList newValue = new ArrayList();
 newValue.add(originalValue);
 newValue.add(value);
 return newValue;
 }
 }
 
 }