How to convert the jsonStr to Observable<T> when use Retrofit - retrofit

I wrote a Interface for Retrofit,
public interface MyService {
#POST("/api/index")
<T> Observable<T> doRequest(#Body Object request);
}
then build the service,
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://localtest.com")
.setConverter(new FastJsonConverter())
.setRequestInterceptor(new CookiesInterceptor(LApplication.getInstance()))
.build();
this.service = restAdapter.create(MyService.class);
when I do request:
Observable<Response> resp = service.doRequest(getRequest())
resp.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(maoApi.mSubscriber);
but the converter cannot converjson to Response Object?
I print out the Type in FastJsonConverter:fromBody(TypedInput body, Type type)
the type is T.
also when use Gson , is still has this problem...
How to solve this problem? or is my design is uncorrect?

Related

Accessing parameters sent to the Custom Logger .NETCore 3.1

I am trying to implement custom ILogger . NetCore 3.1
CustomLogger class implements the ILogger. one of the methods thats need to be implemented is:
public class AuditLogLogger: ILogger
{
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
// How can I access the parameters I sent it from the controller?
}
}
From My controller I triggered the LogInformation Method and passeed a string,
and a List of KeyValuePair as such:
List<KeyValuePair<string, string>> udf = new List<KeyValuePair<string, string>>();
udf.Add(new KeyValuePair<string, string>("Test", "Test"));
_logger.LogInformation("This is a test", udf);
My code is able to make it to the Log<TState> but I need to perform some logic based on the parameters passed in. How can I access the parameters passed?
I ended up doing a dirty solution
Basically, have my controller send in a json string containing the list and message then have the Log function deserialize it such as
string message = "this is a test";
List<KeyValuePair<string, string>> udf = new List<KeyValuePair<string, string();
udf.Add(new KeyValuePair<string, string>("Test", "Test"));
JObject obj = new JObject();
obj["Message"] = message;
obj["MyList"] = JArray.FromObject(udf);
The Log Message needs to deserialize
I am sure there is a cleaner solution

Pact Basic test fails

I am trying a simple pact test but its failing giving the error. Below is my code. Is there any issue with the way I'm trying to call pact.
ERROR:
groovy.json.JsonException: Unable to determine the current character, it is not a string, number, array, or object The current character read is 'T' with an int value of 84
CODE
public class PactTest1 {
#Rule
//public PactProviderRule rule = new PactProviderRule("assessments", this);
public PactProviderRule provider = new PactProviderRule("test_provider", "localhost", 8080, this);
#Pact(state = "default", provider = "test_provider", consumer = "test_consumer")
public PactFragment createFragment(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<>();
headers.put("content-type", "application/json");
return builder
.given("test GET")
.uponReceiving("GET REQUEST")
.path("/assessments")
.method("GET")
.willRespondWith()
.status(200)
.headers(headers)
.body("Test Successful")
.toFragment();
}
#Test
#PactVerification("test_provider")
public void runTest() {
final RestTemplate call = new RestTemplate();
// when
final String response = call.getForObject(provider.getConfig().url()+"/assessments", String.class);
assertEquals(response, "Test Successful");
}
}
It worked after the changed the header content type to text/json. However I'm not able to find the pact file. Where can I find it?

Spring boot 1.5.7 uploading file along with params using RestTemplate

I am getting myself familiar to Springboot. We are creating this Microservice based architecture were I am trying to consume this file upload service using RestTemplate.
Basically the Serve Side API code is
#PostMapping("/upload")
public ResponseEntity<?> fileUpload(#RequestParam String appender,
#RequestParam("file") MultipartFile file) {
...
}
Now on the client side
#Override
public String attachFile(String id, MultipartFile file) {
String status = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> upParams = new LinkedMultiValueMap<String,
Object>();
upParams.add("appender", id);
upParams.add("file", file.getOriginalFilename());
HttpEntity<MultiValueMap<String, Object>> request =
new HttpEntity<MultiValueMap<String, Object>>(upParams, headers);
String response = restTemplate.postForObject(uploadEndPoint, request,
String.class);
return status;
}
I get this error
org.springframework.web.client.HttpServerErrorException: 500
and if I change the line to below
upParams.add("file", file);
I get Error
"Could not write JSON: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile[\"inputStream\"]->java.io.FileInputStream[\"fd\"])

Got InvalidOperationException when trying to access post data in custom filter

I am developing asp.net core web application. When i try to access post data in custom filter, like this:
public class CustomFilter : Attribute, IAsyncActionFilter
{
private ActionExecutingContext _context;
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
_context = context;
var dict = _context.HttpContext.Request.Form.ToDictionary(x => x.Key, x => x.Value.ToString()); // got error her
//int id = dict[“id”];
...
I got this exception
InvalidOperationException: Incorrect Content-Type: application/json.
I use XMLHttpRequest to sent data to server. Here is configuration:
var xhr = new XMLHttpRequest();
xhr.open(“post”, url, true);
xhr.setRequestHeader('Content-Type', 'application/jso
xhr.send(JSON.stringify(dataToSent));
If you POST application/json body (with valid JSON inside) you cann't treat it as form data (which is usually application/x-www-form-urlencoded). Read raw body and deserialize it:
public class CustomFilter : Attribute, IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context,
ActionExecutionDelegate next)
{
var stream = context.HttpContext.Request.Body;
string json = new StreamReader(stream).ReadToEnd();
//Foo obj = JsonConvert.DeserializeObject<Foo>();
}
}

Get Html response with Retrofit

I'm new to Retrofit. I make a POST request to a website. Website returns response as HTML. So I will parse it. However Retrofit try to parse it as JSON. How can do it?
#FormUrlEncoded
#POST("/login.php?action=login")
void postCredentials(#Field("username") String username,
#Field("password") String password);
Should I use a callback?
Retrofit uses a converter to process responses from endpoints and requests as well. By default, Retrofit uses GsonConverter, which encoded JSON responses to Java objects using the gson library. You can override that to supply your own converter when constructing your Retrofit instance.
The interface you need to implement is available here (github.com). Here's a short tutorial as well, although for using Jackson library, many bits are still relevant: futurestud.io/blog
Also note that the converter works both ways, converting requests and responses. Since you want HTML parsing in one direction only, you may want to use GsonConverter in your custom converter, to convert outgoing Java objects to JSON, in the toBody method.
May be not the best solution but this how i managed to get the source of an html page with retrofit:
MainActivity.java
ApiInterface apiService = ApiClient.getClient(context).create(ApiInterface.class);
//Because synchrone in the main thread, i don't respect myself :p
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
//Execution of the call
Call<ResponseBody> call = apiService.url();
response = call.execute();
//Decode the response text/html (gzip encoded)
ByteArrayInputStream bais = new ByteArrayInputStream(((ResponseBody)response.body()).bytes());
GZIPInputStream gzis = new GZIPInputStream(bais);
InputStreamReader reader = new InputStreamReader(gzis);
BufferedReader in = new BufferedReader(reader);
String readed;
while ((readed = in.readLine()) != null) {
System.out.println(readed); //Log the result
}
ApiInterface.java
#GET("/")
Call<ResponseBody> url();
ApiClient.java
public static final String BASE_URL = "https://www.google.com";
private static Retrofit retrofit = null;
public static Retrofit getClient(Context context) {
if (retrofit==null) {
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClient)
.build();
}
return retrofit;
}

Resources