I have working flow for getting files from single folder present in remote server using inbound adopter but i want for get files for all subfolder present in any remote server parent folder
I have code like this
#Bean
public SessionFactory<SftpClient.DirEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
factory.setHost("localhost");
factory.setPort(port);
factory.setUser("foo");
factory.setPassword("foo");
factory.setAllowUnknownKeys(true);
factory.setTestSession(true);
return new CachingSessionFactory<>(factory);
}
#Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
fileSynchronizer.setDeleteRemoteFiles(false);
fileSynchronizer.setRemoteDirectory("foo");
fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xml"));
return fileSynchronizer;
}
#Bean
#InboundChannelAdapter(channel = "sftpChannel", poller = #Poller(fixedDelay = "5000"))
public MessageSource<File> sftpMessageSource() {
SftpInboundFileSynchronizingMessageSource source =
new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
source.setLocalDirectory(new File("sftp-inbound"));
source.setAutoCreateLocalDirectory(true);
source.setLocalFilter(new AcceptOnceFileListFilter<File>());
source.setMaxFetchSize(1);
return source;
}
#Bean
#ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) throws MessagingException {
System.out.println(message.getPayload());
}
};
}`
but instead of single folder i want get files for all subfolder present in foo directory
if possible please help with full code
#GaryRussell
Thanks you so much for you early response .I have done some changes according to your suggested code app is started but files is not getting picked up by application.
CompositeFileListFilter<LsEntry> compositeFileListFilter = new CompositeFileListFilter<>();
SftpPersistentAcceptOnceFileListFilter fileListFilter =
new SftpPersistentAcceptOnceFileListFilter(
(JdbcMetadataStore) context.getBean("metadataStore"), "REMOTE");
if (Constants.APP1.equals(appName) || Constants.APP2.equals(appName)) {
SftpRegexPatternFileListFilter regexPatternFileListFilter =
new SftpRegexPatternFileListFilter(Pattern.compile("^IL.*"));
compositeFileListFilter.addFilter(regexPatternFileListFilter);
}
compositeFileListFilter.addFilter(fileListFilter);
return IntegrationFlows.fromSupplier(
() -> sftpEnvironment.getSftpGLSIncomingDir(), // remote dir
e -> e.autoStartup(true).poller(pollerMetada()))
.handle(
Sftp.outboundGateway(sftpSessionFactory(), Command.MGET, "payload")
.options(Option.RECURSIVE)
.filter(compositeFileListFilter)
.fileExistsMode(FileExistsMode.IGNORE)
.localDirectoryExpression("'/tmp/' + #remoteDirectory")) // re-create tree locally
.split()
.log()
.get();
#GaryRussell
I have changed my code this new way it is partially processing files mean one example out of 10 file only process 5 or 6 files. I am not able to figure the main issue in that.and I also have also some open challenges which i am mentioning below
Its able to read files form remote subdirectories and store in local directory but I want to process these file in some other sftpChannel, if posible without storing locally
I also want to apply some deduplication technique using data base which will help me to avoid duplicate file processing.
public class SFTPPollerService {
#Bean
public SessionFactory<LsEntry> sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
//code
return factory;
}
//OLD code
// #Bean
// public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
// SftpInboundFileSynchronizer fileSynchronizer =
// new SftpInboundFileSynchronizer(sftpSessionFactory());
// fileSynchronizer.setDeleteRemoteFiles(sftpEnvironment.isDeleteRemoteFiles());
// fileSynchronizer.setRemoteDirectory(sftpEnvironment.getSftpGLSIncomingDir());
// fileSynchronizer.setPreserveTimestamp(true);
// CompositeFileListFilter<LsEntry> compositeFileListFilter = new
// CompositeFileListFilter<>();
// SftpPersistentAcceptOnceFileListFilter fileListFilter =
// new SftpPersistentAcceptOnceFileListFilter(
// (JdbcMetadataStore) context.getBean("metadataStore"), "REMOTE");
// if (Constants.app2.equals(appName)
// || Constants.app1.equals(appName)) {
// SftpRegexPatternFileListFilter regexPatternFileListFilter =
// new SftpRegexPatternFileListFilter(Pattern.compile("*.txt"));
// compositeFileListFilter.addFilter(regexPatternFileListFilter);
// }
// compositeFileListFilter.addFilter(fileListFilter);
// fileSynchronizer.setFilter(compositeFileListFilter);
// return fileSynchronizer;
// }
//
// #Bean
// #InboundChannelAdapter(channel = "sftpChannel", poller = #Poller("pollerMetada"))
// public MessageSource<File> sftpMessageSource() {
// SftpInboundFileSynchronizingMessageSource source =
// new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
// source.setLocalDirectory(new File(sftpEnvironment.getSftpLocalDir()));
//
// source.setAutoCreateLocalDirectory(true);
//
// try {
// source.setLocalFilter(
// (FileSystemPersistentAcceptOnceFileListFilter)
// context.getBean("filelistFilter"));
// } catch (Exception e) {
// LOG.error(
// "Exception caught while setting local filter on
// SftpInboundFileSynchronizingMessageSource",
// e);
// }
// source.setMaxFetchSize(sftpEnvironment.getMaxFetchFileSize());
//
// return source;
// }
//new Code
#Bean
public IntegrationFlow sftpInboundFlow() {
CompositeFileListFilter<LsEntry> compositeFileListFilter = new CompositeFileListFilter<>();
SftpPersistentAcceptOnceFileListFilter fileListFilter =
new SftpPersistentAcceptOnceFileListFilter(
(JdbcMetadataStore) context.getBean("metadataStore"), "REMOTE");
if (Constants.app2.equals(appName) || Constants.app1.equals(appName)) {
SftpRegexPatternFileListFilter regexPatternFileListFilter =
new SftpRegexPatternFileListFilter(Pattern.compile("(subDir | *.txt)"));
compositeFileListFilter.addFilter(regexPatternFileListFilter);
}
fileListFilter.setForRecursion(true);
FileSystemPersistentAcceptOnceFileListFilter fileSystemPersistentAcceptOnceFileListFilter = (FileSystemPersistentAcceptOnceFileListFilter) context.getBean(
"filelistFilter");
compositeFileListFilter.addFilter(fileListFilter);
// IntegrationFlow ir =
// IntegrationFlows.from(
// Sftp.inboundAdapter(sftpSessionFactory())
// .preserveTimestamp(true)
// .remoteDirectory(sftpEnvironment.getSftpGLSIncomingDir())
// .deleteRemoteFiles(sftpEnvironment.isDeleteRemoteFiles())
// .filter(compositeFileListFilter)
// .autoCreateLocalDirectory(true)
// .localDirectory(new File(sftpEnvironment.getSftpLocalDir())),
// e -> e.autoStartup(true).poller(pollerMetada()))
// .handle(handler())
// .get();
return IntegrationFlows.fromSupplier(
() -> sftpEnvironment.getSftpGLSIncomingDir(), // remote dir
e -> e.autoStartup(true).poller(pollerMetada()))
.handle(
Sftp.outboundGateway(sftpSessionFactory(), Command.MGET, "payload")
.options(Option.RECURSIVE)
.fileExistsMode(FileExistsMode.IGNORE)
.regexFileNameFilter("(dsv[0-9]|.*.xml)")
// .filter(compositeFileListFilter)
.localDirectoryExpression("'user/localDir/test/'"))
// .handle(handler())
// .patternFileNameFilter(".*\\.xml")) // re-create tree locally
.split()
.channel("sftpChannel")
// .handle(handler())
.log()
.get();
}
#Bean
public PollerMetadata pollerMetada() {
PollerMetadata pm = new PollerMetadata();
ExpressionEvaluatingTransactionSynchronizationProcessor processor =
new ExpressionEvaluatingTransactionSynchronizationProcessor();
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("payload.delete()");
processor.setAfterRollbackExpression(exp);
TransactionSynchronizationFactory tsf = new DefaultTransactionSynchronizationFactory(processor);
pm.setTransactionSynchronizationFactory(tsf);
List<Advice> advices = new ArrayList<>();
advices.add(compoundTriggerAdvice());
pm.setAdviceChain(advices);
pm.setTrigger(compoundTrigger());
pm.setMaxMessagesPerPoll(sftpEnvironment.getMaxMessagesPerPoll());
return pm;
}
#Bean
public CronTrigger cronTrigger() {
if (LOG.isDebugEnabled()) {
return new CronTrigger(sftpEnvironment.getPollerCronExpressionWhenDebugModeIsEnabled());
} else {
return new CronTrigger(sftpEnvironment.getPollerCronExpression());
}
}
#Bean
public PeriodicTrigger periodicTrigger() {
return new PeriodicTrigger(sftpEnvironment.getPeriodicTriggerInMillis());
}
#Bean
public CompoundTrigger compoundTrigger() {
return new CompoundTrigger(cronTrigger());
}
#Bean
public CompoundTriggerAdvice compoundTriggerAdvice() {
return new CompoundTriggerAdvice(compoundTrigger(), periodicTrigger());
}
#Bean
public FileSystemPersistentAcceptOnceFileListFilter filelistFilter(MetadataStore datastore) {
return new FileSystemPersistentAcceptOnceFileListFilter((JdbcMetadataStore) datastore, "INT");
}
#Bean
public PlatformTransactionManager transactionManager() {
return new org.springframework.integration.transaction.PseudoTransactionManager();
}
#Bean
DataSource dataSource() throws SQLException {
OracleDataSource dataSource = new OracleDataSource();
dataSource.setUser(databaseProperties.getOracleUsername());
dataSource.setPassword(databaseProperties.getOraclePassword());
dataSource.setURL(databaseProperties.getOracleUrl());
dataSource.setImplicitCachingEnabled(true);
dataSource.setFastConnectionFailoverEnabled(true);
return dataSource;
}
/**
* Creates a {#link JdbcMetadataStore} for the de-duplication logic.
*
* <p>This method uses the "REGION" column of the metadatastore table to differentiate between
* multiple apps. The value of the "REGION" column is set equal to the app-name.
*
* #return a JDBC metadata store
* #throws SQLException in case an exception occurs during connection to SQL database
*/
#Bean
public MetadataStore metadataStore() throws SQLException {
JdbcMetadataStore jdbcMetadataStore = new JdbcMetadataStore(dataSource());
if (!Constants.app2.equals(appName)) {
jdbcMetadataStore.setRegion(appName);
}
return jdbcMetadataStore;
}
#Bean
#ServiceActivator(inputChannel = "sftpChannel")
public MessageHandler handler() {
return message -> {
File file = (File) message.getPayload();
FileDto fileDto = new FileDto(file);
fileHandler.handle(fileDto);
LOG.info("controller is here ");
try {
if (sftpEnvironment.isDeleteLocalFiles()) {
Files.deleteIfExists(Paths.get(file.toString()));
}
} catch (IOException e) {
// TODO retry/report/handle gracefully
LOG.error(String.format("MessageHandler had error message=%s", message), e);
}
};
}
}
The synchronizer doesn't support recursion. Use the outbound gateway with a recursive mget command instead.
https://docs.spring.io/spring-integration/docs/current/reference/html/sftp.html#sftp-outbound-gateway
Using the mget Command
mget retrieves multiple remote files based on a pattern and supports the following options:
-P: Preserve the timestamps of the remote files.
-R: Retrieve the entire directory tree recursively.
-x: Throw an exception if no files match the pattern (otherwise, an empty list is returned).
-D: Delete each remote file after successful transfer. If the transfer is ignored, the remote file is not deleted, because the FileExistsMode is IGNORE and the local file already exists.
The message payload resulting from an mget operation is a List<File> object (that is, a List of File objects, each representing a retrieved file).
EDIT
Here is an example using the java DSL...
#SpringBootApplication
public class So75180789Application {
public static void main(String[] args) {
SpringApplication.run(So75180789Application.class, args);
}
#Bean
IntegrationFlow flow(DefaultSftpSessionFactory sf) {
return IntegrationFlows.fromSupplier(() -> "foo/*", // remote dir
e -> e.poller(Pollers.fixedDelay(5000)))
.handle(Sftp.outboundGateway(sf, Command.MGET, "payload")
.options(Option.RECURSIVE)
.fileExistsMode(FileExistsMode.IGNORE)
.localDirectoryExpression("'/tmp/' + #remoteDirectory")) // re-create tree locally
.split()
.log()
.get();
}
#Bean
DefaultSftpSessionFactory sf(#Value("${host}") String host,
#Value("${username}") String user, #Value("${pw}") String pw) {
DefaultSftpSessionFactory sf = new DefaultSftpSessionFactory();
sf.setHost(host);
sf.setUser(user);
sf.setPassword(pw);
sf.setAllowUnknownKeys(true);
return sf;
}
}
I wanna create an application to send emails to several recipients. It feeds email addresses from a csv file and sends an email to each recipient, and I'm getting some trouble doing this.
Could you help me please?
Here is my CSVHelper.java
#Component
public class CSVHelper
{
public static String TYPE = "text/csv";
static String[] HEADERs = { "id", "email", "dateEcheance"};
//This method is used to filter the csv file and get only the emails
public List<ContactsFile> csvToEmails() throws NumberFormatException, ParseException
{
InputStream is = null;
try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader, CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());)
{
List<ContactsFile> emailsList = new ArrayList<>();
Iterable<CSVRecord> csvRecords = csvParser.getRecords();
for (CSVRecord csvRecord : csvRecords)
{
ContactsFile contact = new ContactsFile(csvRecord.get("email"));
emailsList.add(contact);
}
System.out.println(emailsList);
return emailsList;
}
catch (IOException e) { throw new RuntimeException("fail to get emails: " + e.getMessage()); }
}
We call csvToEmails() method in the controller to send the emails
#Autowired
private CSVHelper csvHelper;
#PostMapping("/getdetails")
public #ResponseBody EmailNotification sendMail(#RequestBody EmailNotification details) throws Exception {
MimeMessage message = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
try {
helper.setTo((InternetAddress) csvHelper.csvToEmails());
helper.setText(details.getMessage(),true);
helper.setSubject("Test Mail");
} catch (javax.mail.MessagingException e) {
e.printStackTrace();
}
sender.send(message);
return details;
this is an example of the csv file:
id,email,dateEcheance
1,address#email.com,10/05/2021
2,address2#email.com,10/02/2021
I'm new to spring boot, and I'm in trouble completing this project.
Assuming that you've mail server configurations in place. First, you need to provide the JavaMailSender implementation. Spring does provide the implementation for the same. You've to create a bean and config the mail server configurations as follows.
#Configuration
public class MailConfig {
#Autowired
private Environment env;
#Bean
public JavaMailSender mailSender() {
try {
JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
mailSenderImpl.setHost(env.getRequiredProperty("mail.smtp.host"));
mailSenderImpl.setUsername(env.getRequiredProperty("mail.smtp.username"));
mailSenderImpl.setPassword(env.getRequiredProperty("mail.smtp.password"));
mailSenderImpl.setDefaultEncoding(env.getRequiredProperty("mail.smtp.encoding"));
mailSenderImpl.setPort(Integer.parseInt(env.getRequiredProperty("mail.smtp.port")));
mailSenderImpl.setProtocol(env.getRequiredProperty("mail.transport.protocol"));
Properties p = new Properties();
p.setProperty("mail.smtp.starttls.enable", "true");
p.setProperty("mail.smtp.auth", "true");
mailSenderImpl.setJavaMailProperties(p);
return mailSenderImpl;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Configuration settings in application.properties. Add settings according to the mail server.
# SMTP mail settings
mail.smtp.host=**********
mail.smtp.username=**********
mail.smtp.password=**********
mail.smtp.port=**********
mail.smtp.socketFactory.port=**********
mail.smtp.encoding=utf-8
mail.transport.protocol=smtp
mail.smtp.auth=true
mail.smtp.timeout=10000
mail.smtp.starttls.enable=true
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
CSVHelper.java
#Component
public class CSVHelper {
// This method is used to filter the csv file and get only the emails
public List<String> csvToEmails() {
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("csvFile.csv");
try (BufferedReader fileReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
CSVParser csvParser = new CSVParser(fileReader,
CSVFormat.DEFAULT.withFirstRecordAsHeader().withIgnoreHeaderCase().withTrim());) {
List<String> emails = new ArrayList<>();
Iterable<CSVRecord> csvRecords = csvParser.getRecords();
for (CSVRecord csvRecord : csvRecords) {
String email = csvRecord.get("email");
emails.add(email);
}
return emails;
} catch (IOException e) {
throw new RuntimeException("fail to get emails: " + e.getMessage());
}
}
}
Send mail service
#Service
public class MailSenderService {
#Autowired
private CSVHelper csvHelper;
#Autowired
private JavaMailSender sender;
public void sendMail(EmailNotification details) {
try {
List<String> recipients = csvHelper.csvToEmails();
String[] to = recipients.stream().toArray(String[]::new);
JavaMailSenderImpl jms = (JavaMailSenderImpl) sender;
MimeMessage message = jms.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// add the sender email address below
helper.setFrom("sender#mail.com");
helper.setTo(to);
helper.setText(details.getMessage(), true);
helper.setSubject("Test Mail");
sender.send(message);
} catch (javax.mail.MessagingException | NumberFormatException e) {
// action for exception case
}
}
}
I am trying to display array data using JSON Volley in PostsBasedOnCategory.java. Array data that I want to display are, Title post, and excerpt based on specific category from https://www.kisahmuslim.com/wp-json/wp/v2/categories. But unfortunately, it only showing one result.
Below you can check my code
DaftarCategories.java
public class CallingPage extends AsyncTask<String, String, String> {
HttpURLConnection conn;
java.net.URL url = null;
private int page = 1;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
showNoFav(false);
pb.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(String... params) {
try {
url = new URL("https://www.kisahmuslim.com/wp-json/wp/v2/categories");
}
catch(MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return("koneksi gagal");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
protected void onPostExecute(String result)
{
JsonArrayRequest stringRequest = new JsonArrayRequest(Request.Method.GET, SumberPosts.HOST_URL+"wp/v2/categories/", null, new Response.Listener<JSONArray>()
{
#Override
public void onResponse(JSONArray response) {
// display response
Log.d(TAG, response.toString() + "Size: "+response.length());
// agar setiap kali direfresh data tidak redundant
typeForPosts.clear();
for(int i=0; i<response.length(); i++) { //ambil semua objek yang ada
final CategoriesModel post = new CategoriesModel();
try {
Log.d(TAG, "Object at " + i + response.get(i));
JSONObject obj = response.getJSONObject(i);
post.setId(obj.getInt("id"));
post.setPostURL(obj.getString("link"));
//Get category name
post.setCategory(obj.getString("name"));
//////////////////////////////////////////////////////////////////////////////////////
// getting article konten
JSONObject postCategoryParent = obj.getJSONObject("_links");
JSONArray postCategoryObj = postCategoryParent.getJSONArray("wp:post_type");
JSONObject postCategoryIndex = postCategoryObj.getJSONObject(0); //ambil satu objek saja
String postCategoryUrl = postCategoryIndex.getString("href"); //satu objek yang dimaksud adalah href
if(postCategoryUrl != null) {
Log.d(TAG, postCategoryIndex.getString("href"));
JsonArrayRequest getKonten = new JsonArrayRequest(Request.Method.GET, postCategoryUrl, null, new Response.Listener<JSONArray>()
{
#Override
public void onResponse(JSONArray respon) {
Log.d(TAG, respon.toString() + "Size: "+respon.length());
for(int d=0; d<respon.length(); d++) {
try {
//Log.d(TAG, "Object at " + i + respon.get());
JSONObject objek = respon.getJSONObject(d); //ambil semua artikel yang tersedia di postCategoryUrl
post.setId(objek.getInt("id"));
post.setCreatedAt(objek.getString("date"));
post.setPostURL(objek.getString("link"));
//Get category title
JSONObject titleObj = objek.getJSONObject("title");
post.setJudul(titleObj.getString("rendered"));
//Get excerpt
JSONObject exerptObj = objek.getJSONObject("excerpt");
post.setExcerpt(exerptObj.getString("rendered"));
// Get content
JSONObject contentObj = objek.getJSONObject("content");
post.setContent(contentObj.getString("rendered"));
}
catch (JSONException e) {
e.printStackTrace();
}
}// for category
} //onResponse2
}, new Response.ErrorListener() { //getKonten
#Override
public void onErrorResponse(VolleyError error) {
pb.setVisibility(View.GONE);
Log.d(TAG, error.toString());
}
});
queue.add(getKonten);
} //if postCategoryUrl
//////////////////////////////////////////////////////////////////////////////////////
typeForPosts.add(post);
} //try 1
catch (JSONException e) {
e.printStackTrace();
}
} //for 1
pb.setVisibility(View.GONE);
recycleViewWordPress.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
} //onResponse1
}, new Response.ErrorListener() { //stringRequest
#Override
public void onErrorResponse(VolleyError error) {
showNoFav(true);
pb.setVisibility(View.GONE);
Log.e(TAG, "Error: " + error.getMessage());
Toast.makeText(getContext(), "Tidak bisa menampilkan data. Periksa kembali sambungan internet Anda", Toast.LENGTH_LONG).show();
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
} //onPostExecute
} //CallingPage
#Override
public void onPostingSelected(int pos) {
CategoriesModel click = typeForPosts.get(pos);
excerpt = click.getExcerpt();
//gambar = click.getPostImg();
judul = click.getJudul();
//url = click.getPostURL();
content = click.getContent();
Bundle bundle = new Bundle();
bundle.putString("judul", judul);
//bundle.putString("gambar", gambar);
//bundle.putString("url", url);
bundle.putString("content", content);
bundle.putString("excerpt", excerpt);
PostsBasedOnCategory bookFragment = new PostsBasedOnCategory();
bookFragment.setArguments(bundle);
AppCompatActivity activity = (AppCompatActivity) getContext();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.flContainerFragment, bookFragment).addToBackStack(null).commit();
}
PostsBasedOnCategory.java
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_wordpress, container,false);
ButterKnife.bind(this,view);
setHasOptionsMenu(true);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
swipeRefreshLayout =(SwipeRefreshLayout) getActivity().findViewById(R.id.swipeRefreshLayout);
recycleViewWordPress =(RecyclerView) getActivity().findViewById(R.id.recycleViewWordPress);
pb = (ProgressBar) getActivity().findViewById(R.id.loadingPanel);
noFavtsTV = getActivity().findViewById(R.id.no_favt_text);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeRefreshLayout.setRefreshing(false);
pb.setVisibility(View.VISIBLE);
recycleViewWordPress.setAdapter(mAdapter);
}
});
typeForPosts = new ArrayList<CategoriesModel>();
recycleViewWordPress.setHasFixedSize(true);
recycleViewWordPress.setLayoutManager(new LinearLayoutManager(getContext()));
recycleViewWordPress.setNestedScrollingEnabled(false);
mAdapter = new AdapterCategoryPosts(getContext(), typeForPosts, this);
recycleViewWordPress.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
loadData();
}
public void loadData() {
Bundle bundel = this.getArguments();
long id = bundel.getLong("id");
String kategori = bundel.getString("kategori");
String title = bundel.getString("judul");
String excerpt = bundel.getString("excerpt");
String pict = bundel.getString("gambar");
String url = bundel.getString("url");
String konten = bundel.getString("konten");
CategoriesModel list = new CategoriesModel();
list.setId(id);
list.setCategory(kategori);
list.setJudul(title);
list.setExcerpt(excerpt);
list.setPostImg(pict);
list.setPostURL(url);
list.setContent(konten);
typeForPosts.add(list);
}
Logcat
2019-09-07 12:01:27.941 11246-11246/com.kursusarabic.arabicforfun D/postFrag: [{"id":12,"count":53,"description":"","link":"https:\/\/kisahmuslim.com\/category\/kisah-nyata\/biografi-ulama","name":"Biografi Ulama","slug":"biografi-ulama","taxonomy":"category","parent":29,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/12"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"up":[{"embeddable":true,"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/29"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":26,"count":8,"description":"","link":"https:\/\/kisahmuslim.com\/category\/download","name":"Download","slug":"download","taxonomy":"category","parent":0,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/26"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=26"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":1812,"count":9,"description":"","link":"https:\/\/kisahmuslim.com\/category\/info","name":"Info","slug":"info","taxonomy":"category","parent":0,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/1812"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=1812"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":17,"count":3,"description":"","link":"https:\/\/kisahmuslim.com\/category\/kisah-nyata\/kisah-birrul-walidain","name":"Kisah Birrul Walidain","slug":"kisah-birrul-walidain","taxonomy":"category","parent":29,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/17"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"up":[{"embeddable":true,"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/29"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=17"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":25,"count":31,"description":"","link":"https:\/\/kisahmuslim.com\/category\/kisah-nyata\/kisah-hidayah-islam","name":"Kisah Hidayah Islam","slug":"kisah-hidayah-islam","taxonomy":"category","parent":29,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/25"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"up":[{"embeddable":true,"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/29"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=25"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}},{"id":16,"count":49,"description":"","link":"https:\/\/kisahmuslim.com\/category\/kisah-nyata\/kisah-kaum-durhaka","name":"Kisah Kaum Durhaka","slug":"kisah-kaum-durhaka","taxonomy":"category","parent":29,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/16"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"up":[{"embeddable":true,"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/29"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=1
2019-09-07 12:01:27.942 11246-11246/com.kursusarabic.arabicforfun D/postFrag: Object at 0{"id":12,"count":53,"description":"","link":"https:\/\/kisahmuslim.com\/category\/kisah-nyata\/biografi-ulama","name":"Biografi Ulama","slug":"biografi-ulama","taxonomy":"category","parent":29,"meta":[],"_links":{"self":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/12"}],"collection":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories"}],"about":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/taxonomies\/category"}],"up":[{"embeddable":true,"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/categories\/29"}],"wp:post_type":[{"href":"https:\/\/kisahmuslim.com\/wp-json\/wp\/v2\/posts?categories=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}
2019-09-07 12:01:27.942 11246-11246/com.kursusarabic.arabicforfun D/postFrag: https://kisahmuslim.com/wp-json/wp/v2/posts?categories=12
You cannot call network requests in loop, Use async processing or
Retrofit & RxJava multiple requests complete
and after updating typeForPosts, there is no need to setAdapter on recyclerview just call adapter.notifyDataSetChanged()
In spring boot 1.4.2.RELEASE, PropertiesConfigurationFactory has method setProperties(Properties properties).
So my code can write as follow:
public Map<String, CacheProperties> resolve() {
Map<String, Object> cacheSettings = resolveCacheSettings();
Set<String> beanNames = resolveCacheManagerBeanNames(cacheSettings);
Map<String, CacheProperties> cachePropertiesMap = new HashMap<>(beanNames.size());
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new MapPropertySource("cache", cacheSettings));
beanNames.forEach(beanName -> {
CacheProperties cacheProperties = new CacheProperties();
PropertiesConfigurationFactory<CacheProperties> factory = new PropertiesConfigurationFactory<>(cacheProperties);
Properties properties = new Properties();
properties.putAll(PropertySourceUtils.getSubProperties(propertySources, beanName));
factory.setProperties(properties);
factory.setConversionService(environment.getConversionService());
try {
factory.bindPropertiesToTarget();
cachePropertiesMap.put(beanName, cacheProperties);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
return cachePropertiesMap;
}
But when I upgrade to spring boot 1.5.8.RELEASE. PropertiesConfigurationFactory changed the method setProperties(Properties properties) to setPropertySources(PropertySources propertySources).
So I changed my code like this:
public Map<String, CacheProperties> resolve() {
Map<String, Object> cacheSettings = resolveCacheSettings();
Set<String> beanNames = resolveCacheManagerBeanNames(cacheSettings);
Map<String, CacheProperties> cachePropertiesMap = new HashMap<>(beanNames.size());
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new MapPropertySource("cache", cacheSettings));
beanNames.forEach(beanName -> {
CacheProperties cacheProperties = new CacheProperties();
PropertiesConfigurationFactory<CacheProperties> factory = new PropertiesConfigurationFactory<>(cacheProperties);
//Properties properties = new Properties();
//properties.putAll(PropertySourceUtils.getSubProperties(propertySources, beanName));
//factory.setProperties(properties);
factory.setPropertySources(propertySources);
factory.setConversionService(environment.getConversionService());
try {
factory.bindPropertiesToTarget();
cachePropertiesMap.put(beanName, cacheProperties);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
return cachePropertiesMap;
}
But this not work...
Anyone can help me? How to convert Properties to PropertySources?
Resolved...
I add factory.setTargetName(beanName); before factory.setPropertySources(propertySources);, and it works well.