Here is my json URL https://jsonplaceholder.typicode.com/todos I want to display only completed: true is to be strike through, how can I do that?
MainActivity.java
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
JsonPlaceHolderApi jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
Call<List<Post>> call = jsonPlaceHolderApi.getPosts();
call.enqueue(new Callback<List<Post>>() {
#Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
if (!response.isSuccessful()) {
textresult.setText("Code: " + response.code());
return;
}
List<Post> posts = response.body();
for (Post post : posts) {
String content = "";
content += "User ID: " + post.getUserId() + "\n";
content += "ID: " + post.getId() + "\n";
content += " Title: " + post.getTitle() + "\n";
content += "Completed: " + post.getCompleted() + "\n\n";
textresult.append(content);
if (post.getCompleted().contains("true")) {
textresult.setPaintFlags(textresult.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
}
}
#Override
public void onFailure(Call<List<Post>> call, Throwable t) {
textresult.setText(t.getMessage());
}
});
JsonPlaceHolderApi.java
public interface JsonPlaceHolderApi {
#GET("todos")
Call<List<Post>> getPosts();
}
Post.java
public class Post {
private int userId;
private int id;
private String title;
private String completed;
public int getUserId() {
return userId;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public String getCompleted() {
return completed;
}
}
When I try to run the above code I got output as image, but I need if completed: true it should be strike.
it is not possible to do setPaintFlags() with custom text better use can use HTML text for your work for you don't need to check "post.complete()", just append all content in a single string and replace your target string (complete: true) with HTML text.
just do it like
String content = "";
for (Post post : posts) {
content += "User ID: " + post.getUserId() + "\n";
content += "ID: " + post.getId() + "\n";
content += " Title: " + post.getTitle() + "\n";
content += "Completed: " + post.getCompleted() + "\n\n";
}
String tempHtmlText = content.replaceAll("Completed: true","<strike>Completed: true</strike>");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textresult.setText(Html.fromHtml(tempHtmlText , Html.FROM_HTML_MODE_LEGACY));
} else {
textresult.setText(Html.fromHtml(tempHtmlText));
}
or you can use Gson formmater
Related
I am new to Jsoup parsing and I want to get the list of all the companies on this page: https://angel.co/companies?company_types[]=Startup
Now, a way to do this is actually to inspect the page with the div tags relevant to what I need.
However, when I call the method :
Document doc = Jsoup.connect("https://angel.co/companies?company_types[]=Startup").get();
System.out.println(doc.html());
Firstly I cannot even find those DIV tags in my consol html output, (the ones which are supposed to give a list of the companies)
Secondly, even if I did find it, how can I find a certain Div element with class name :
div class=" dc59 frw44 _a _jm"
Pardon the jargon, I have no idea how to go through this.
The data are not embedded in the page but they are retrieved using subsequent API calls :
a POST https://angel.co/company_filters/search_data to get an ids array & a token named hexdigest
a GET https://angel.co/companies/startups to retrieve company data using the output from the previous request
The above is repeated for each page (thus a new token & a list of ids are needed for each page). This process can be seen using Chrome dev console in Network tabs.
The first POST request gives JSON output but the second request (GET) gives HTML data in a property of a JSON object.
The following extracts the company filter :
private static CompanyFilter getCompanyFilter(final String filter, final int page) throws IOException {
String response = Jsoup.connect("https://angel.co/company_filters/search_data")
.header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
.header("X-Requested-With", "XMLHttpRequest")
.data("filter_data[company_types][]=", filter)
.data("sort", "signal")
.data("page", String.valueOf(page))
.userAgent("Mozilla")
.ignoreContentType(true)
.post().body().text();
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
return gson.fromJson(response, CompanyFilter.class);
}
Then the following extracts companies :
private static List<Company> getCompanies(final CompanyFilter companyFilter) throws IOException {
List<Company> companies = new ArrayList<>();
URLConnection urlConn = new URL("https://angel.co/companies/startups?" + companyFilter.buildRequest()).openConnection();
urlConn.setRequestProperty("User-Agent", "Mozilla");
urlConn.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
HtmlContainer htmlObj = new Gson().fromJson(reader, HtmlContainer.class);
Element doc = Jsoup.parse(htmlObj.getHtml());
Elements data = doc.select("div[data-_tn]");
if (data.size() > 0) {
for (int i = 2; i < data.size(); i++) {
companies.add(new Company(data.get(i).select("a").first().attr("title"),
data.get(i).select("a").first().attr("href"),
data.get(i).select("div.pitch").first().text()));
}
} else {
System.out.println("no data");
}
return companies;
}
The main function :
public static void main(String[] args) throws IOException {
int pageCount = 1;
List<Company> companies = new ArrayList<>();
for (int i = 0; i < 10; i++) {
System.out.println("get page n°" + pageCount);
CompanyFilter companyFilter = getCompanyFilter("Startup", pageCount);
pageCount++;
System.out.println("digest : " + companyFilter.getDigest());
System.out.println("count : " + companyFilter.getTotalCount());
System.out.println("array size : " + companyFilter.getIds().size());
System.out.println("page : " + companyFilter.getpage());
companies.addAll(getCompanies(companyFilter));
if (companies.size() == 0) {
break;
} else {
System.out.println("size : " + companies.size());
}
}
}
Company, CompanyFilter & HtmlContainer are model class :
class CompanyFilter {
#SerializedName("ids")
private List<Integer> mIds;
#SerializedName("hexdigest")
private String mDigest;
#SerializedName("total")
private String mTotalCount;
#SerializedName("page")
private int mPage;
#SerializedName("sort")
private String mSort;
#SerializedName("new")
private boolean mNew;
public List<Integer> getIds() {
return mIds;
}
public String getDigest() {
return mDigest;
}
public String getTotalCount() {
return mTotalCount;
}
public int getpage() {
return mPage;
}
private String buildRequest() {
String out = "total=" + mTotalCount + "&";
out += "sort=" + mSort + "&";
out += "page=" + mPage + "&";
out += "new=" + mNew + "&";
for (int i = 0; i < mIds.size(); i++) {
out += "ids[]=" + mIds.get(i) + "&";
}
out += "hexdigest=" + mDigest + "&";
return out;
}
}
private static class Company {
private String mLink;
private String mName;
private String mDescription;
public Company(String name, String link, String description) {
mLink = link;
mName = name;
mDescription = description;
}
public String getLink() {
return mLink;
}
public String getName() {
return mName;
}
public String getDescription() {
return mDescription;
}
}
private static class HtmlContainer {
#SerializedName("html")
private String mHtml;
public String getHtml() {
return mHtml;
}
}
The full code is also available here
In my app I make post request to the server with a special code inside the body. Then I should get some information in the response. However, I always get the name of the response class.
My request code:
#POST("/accounts/login/vk-oauth2/")
Call<RegistrationProcessCodeResponse> postCode(#Body CodePostRequest code);
My ResponseClass:
public class RegistrationProcessCodeResponse {
private String message;
private String partial_token;
private String phase;
public String getMessage() {
return message;
}
public String getPartial_token() {
return partial_token;
}
public String getPhase() {
return phase;
}
public void setMessage(String message) {
this.message = message;
}
public void setPartial_token(String partial_token) {
this.partial_token = partial_token;
}
public void setPhase(String phase) {
this.phase = phase;
}
}
My request code:
HseAlumniApi hseAlumniApi = HseAlumniApi.retrofit.create(HseAlumniApi.class);
Call<RegistrationProcessCodeResponse> postComment = hseAlumniApi.postCode(codePostRequest);
postComment.enqueue(new Callback<RegistrationProcessCodeResponse>() {
#Override
public void onResponse(Call<RegistrationProcessCodeResponse> call, Response<RegistrationProcessCodeResponse> response) {
Log.d("myLogs", "String.valueOf(response.code())\n" + String.valueOf(response.code()));
Log.d("myLogs", "response.body().toString()\n" + response.body().toString());
if (response.isSuccessful()) {
Log.d("myLogs", "Request succeeded");
}
}
#Override
public void onFailure(Call<RegistrationProcessCodeResponse> call, Throwable t) {
Log.d("myLogs", "Request failed");
}
});
My logs:
D/myLogs: String.valueOf(response.code())
200
D/myLogs: response.body().toString()
com.example.vitaly.hsealumni.RegistrationProcessCodeResponse#498e7e7
D/myLogs: Request succeeded
Response Json:
{
"message": "email needed",
"partial_token": "231445d4fc5a4ed99dccb681942d5d7e",
"phase": 1
}
I really have no idea what to do, help please
public class RegistrationProcessCodeResponse {
private String message;
private String partial_token;
private String phase;
public RegistrationProcessCodeResponse() {
message = "";
partial_token = "";
phase = "";
}
// getters and setters
#Override
public String toString() {
return "RegistrationProcessCodeResponse{" +
"message='" + message + '\'' +
", partial_token='" + partial_token + '\'' +
", phase='" + phase + '\'' +
'}';
}
}
Hi wrote my own little Logger class to write log output into files, the class looks like this:
public class Logger {
private String prefix;
private String pathToLogFiles = "/tmp/sos/logs/";
private String infoLog;
private String errorLog;
private boolean doLogtoFile;
public Logger(String prefix, Class classname, boolean logToFile) {
this.prefix = "[" + prefix + "]";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date now = new Date();
this.infoLog = this.pathToLogFiles + "info_" + sdf.format(now) + ".log";
this.errorLog = this.pathToLogFiles + "error_" + sdf.format(now) + ".log";
this.doLogtoFile = logToFile;
System.out.println("Will log to: " + this.infoLog + " and " + this.errorLog);
}
public void info(String message) {
String logmessage = prefix + " INFO " + message;
if( this.doLogtoFile ) {
try {
Files.write(Paths.get(infoLog), logmessage.getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
System.out.println(prefix + message);
}
} else {
System.out.println(prefix + message);
}
}
public void error(String message) {
String logmessage = prefix + " ERROR " + message;
if( this.doLogtoFile ) {
try {
Files.write(Paths.get(errorLog), logmessage.getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
System.out.println(prefix + message);
}
} else {
System.out.println(prefix + message);
}
}
}
Permissions of the directory and subdirectories are all set up correctly and owned by the tomcat user. However I don't receive any logoutput, nor are the log files even created.
Could anyone see what could be going wrong?
Strangely enough I am not getting any Exception
Many thanks for any help
I am experiencing an interesting error. I am using mailgun and Retrofit to send e-mails through my application. On the first attempt after opening my application, the send attempt always returns a retrofit error (400 Bad Request). However, all subsequent attempts send through appropriately.
MailGunClient interface:
public interface MailGunClient {
#FormUrlEncoded
#POST("/messages")
void sendMessagePurchase(
#Field("from") String from,
#Field("to") String to,
#Field("h:Reply-To") String replyToAddress,
#Field("subject") String subject,
#Field("text") StringBuilder text,
Callback<Response> responseCallback);
}
Method instantiating the interface and attempting to send (MainActivity):
public void sendResume(String productID) {
if (productID.equals(EMAILSKU)) {
mMailGunClient = new RestAdapter.Builder()
.setEndpoint("https://api.mailgun.net/v3/mg.resumetemplatepro.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
final String credentials = "api" + ":" + "key-c5b8f0c0c7dcaabc23075b977a7b7e43";
final String authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
request.addHeader("Authorization", authString);
}
})
.build().create(MailGunClient.class);
StringBuilder messageBody = new StringBuilder();
messageBody.append("Hello," + "\r\n" + "\r\n");
messageBody.append("Thank you for purchasing a resume. You can view the resume at the following link: " + getResumeTemplateDownloadLink(pager.getCurrentItem()) + "\r\n" + "\r\n");
messageBody.append("Regards," + "\r\n");
messageBody.append("The Resume Template Pro Team");
mMailGunClient.sendMessagePurchase("resume#mg.resumetemplatepro.com", customerEmailAddress, RBPEMAIL, "Resume Template Email",
messageBody, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
System.out.println("Success");
Toast.makeText(getApplication(), R.string.successfully_sent, Toast.LENGTH_SHORT).show();
Apptentive.engage(MainActivity.this, "Post_Sale");
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getApplicationContext(), R.string.try_again, Toast.LENGTH_LONG).show();
}
});
} else if (productID.equals(RESUMECOVERLETTER)) {
mMailGunClient = new RestAdapter.Builder()
.setEndpoint("https://api.mailgun.net/v3/mg.resumetemplatepro.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
final String credentials = "api" + ":" + "key-c5b8f0c0c7dcaabc23075b977a7b7e43";
final String authString = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.DEFAULT);
request.addHeader("Authorization", authString);
}
})
.build().create(MailGunClient.class);
StringBuilder messageBody = new StringBuilder();
messageBody.append("Hello," + "\r\n" + "\r\n");
messageBody.append("The user with e-mail " + customerEmailAddress + " has purchased a professional edit. They purchased " + getResumeTemplateDownloadLink(pager.getCurrentItem()) + "." + "\r\n" + "\r\n");
messageBody.append("Regards," + "\r\n");
messageBody.append("The Resume Template Pro Team");
mMailGunClient.sendMessagePurchase("resume#mg.resumetemplatepro.com", RBPEMAIL, customerEmailAddress, "Resume Template Purchase",
messageBody, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
System.out.println("Success");
Toast.makeText(getApplication(), R.string.edit_purchase, Toast.LENGTH_SHORT).show();
Apptentive.engage(MainActivity.this, "Post_Sale");
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getApplicationContext(), R.string.try_again, Toast.LENGTH_LONG).show();
}
});
} else {
Toast.makeText(MainActivity.this, R.string.error, Toast.LENGTH_SHORT).show();
}
}
How could I get the data from a xml, which is generated with php, in java.
I need the data to display it in a listview in my android app.
The phpcode take the data form the mysqlquery and fetch the array in the variabel xml and put it over echo out. The data for the mysqlquery are from the android app over POST.
phpcode:
//MySQL zugangsdaten
$server = "server";
$datenbank = "database";
$username = "username";
$passwort = "password";
//Verbindung zur MySqldatenbank herstellen
$link = mysql_connect($server, $username, $passwort);
if (!$link) die(mysql_error());
//Datenbank auswählen
$db = mysql_select_db($datenbank, $link);
//<---- End Login ---->
$_linie = htmlspecialchars(mysql_real_escape_string($_POST["linie"]), ENT_COMPAT);
$_richtung = htmlspecialchars(mysql_real_escape_string($_POST["richtung"]), ENT_COMPAT);
$sql_befehl = "SELECT * From Kontrolleure where linie = '$_linie' AND richtung = '$_richtung'";
$query = mysql_query($sql_befehl, $link);
if(mysql_error())
{
die(mysql_error());
}
while($result = mysql_fetch_array($query, MYSQL_ASSOC))
{
$count = $count + 1;
$xml = $xml."<Konduktor>";
$xml = $xml."<id>".$result['id']."</id>";
$xml = $xml."<linie>".$result['linie']."</linie>";
$xml = $xml."<endstation>".$result['richtung']."</endstation>";
$xml = $xml."<station>".$result['station']."</station>";
$xml = $xml."<zeit>".$result['zeit']."</zeit>";
$xml = $xml."</Konduktor>";
}
echo "<Konduktors count=\"$count\">";
echo $xml;
echo "</Konduktors>";
the xml response looks like this:
<Konduktors count="3">
<Konduktor>
<id>29</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Brugg AG</station>
<zeit>17:36:34</zeit>
</Konduktor>
<Konduktor>
<id>30</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Lupfig</station>
<zeit>17:37:12</zeit>
</Konduktor>
<Konduktor>
<id>32</id>
<linie>S23</linie>
<endstation>Langenthal</endstation>
<station>Birr</station>
<zeit>16:23:30</zeit>
</Konduktor>
</Konduktors>
Thank you!
There are xml parsing tools for this kind of thing. At my work we use XMLBeans:
http://xmlbeans.apache.org/
I found using it to be fairly straightforward, and am kind of a rank amateur at this kind of stuff.
JAXB would handle that easily:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
public class JaxbExample {
public static void main(String[] args) throws JAXBException {
String xml =
"<Konduktors count=\"3\">\n" +
" <Konduktor>\n" +
" <id>29</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Brugg AG</station>\n" +
" <zeit>17:36:34</zeit>\n" +
" </Konduktor>\n" +
" <Konduktor>\n" +
" <id>30</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Lupfig</station>\n" +
" <zeit>17:37:12</zeit>\n" +
" </Konduktor>\n" +
" <Konduktor>\n" +
" <id>32</id>\n" +
" <linie>S23</linie>\n" +
" <endstation>Langenthal</endstation>\n" +
" <station>Birr</station>\n" +
" <zeit>16:23:30</zeit>\n" +
" </Konduktor>\n" +
"</Konduktors>";
Object object = JAXBContext.newInstance(Konduktors.class).createUnmarshaller().unmarshal(new StringReader(xml));
System.out.println(object);
}
#XmlRootElement(name = "Konduktors")
static class Konduktors {
private List<Konductor> konductors = new ArrayList<Konductor>();
#XmlElement(name = "Konduktor")
public List<Konductor> getKonductors() {
return konductors;
}
public void setKonductors(List<Konductor> konductors) {
this.konductors = konductors;
}
#Override
public String toString() {
return "Konductors{" +
"konductors=" + konductors +
'}';
}
}
static class Konductor {
private int id;
private String linie;
private String endstation;
private String zeit;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLinie() {
return linie;
}
public void setLinie(String linie) {
this.linie = linie;
}
public String getEndstation() {
return endstation;
}
public void setEndstation(String endstation) {
this.endstation = endstation;
}
public String getZeit() {
return zeit;
}
public void setZeit(String zeit) {
this.zeit = zeit;
}
#Override
public String toString() {
return "Konductor{" +
"id=" + id +
", linie='" + linie + '\'' +
", endstation='" + endstation + '\'' +
", zeit='" + zeit + '\'' +
'}';
}
}
}
Other options include XStream or XMLBeans for higher-level abstractions and dom4j or JDOM for lower-level ones--you have to do more work with these but have a lot more flexibility.