Pubblica un collegamento all'API di Reddit

Top di sicurezza

Ho appena annunciato il nuovo corso Learn Spring Security, incluso il materiale completo incentrato sul nuovo stack OAuth2 in Spring Security 5:

>> SCOPRI IL RESTO DEL CORSO Top

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO

1. Panoramica

In questo secondo articolo della serie, costruiremo alcune semplici funzionalità da pubblicare su Reddit dalla nostra applicazione, tramite la loro API.

2. Sicurezza necessaria

Primo: togliamo l'aspetto della sicurezza.

Per inviare un collegamento a Reddit , dobbiamo definire una risorsa protetta da OAuth con l' ambito di " invio ":

@Bean public OAuth2ProtectedResourceDetails reddit() { AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails(); details.setId("reddit"); details.setClientId(clientID); details.setClientSecret(clientSecret); details.setAccessTokenUri(accessTokenUri); details.setUserAuthorizationUri(userAuthorizationUri); details.setTokenName("oauth_token"); details.setScope(Arrays.asList("identity", "submit")); details.setGrantType("authorization_code"); return details; }

Tieni presente che stiamo anche specificando l' ambito " identità " perché abbiamo anche bisogno di accedere alle informazioni sull'account utente.

3. È necessario il captcha?

Gli utenti che sono nuovi su Reddit devono compilare un Captcha per inviare; cioè prima che superino una certa soglia di karma all'interno di Reddit.

Per questi utenti, dobbiamo prima verificare se è necessario il Captcha:

private String needsCaptcha() { String result = redditRestTemplate.getForObject( "//oauth.reddit.com/api/needs_captcha.json", String.class); return result; } private String getNewCaptcha() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity req = new HttpEntity(headers); Map param = new HashMap(); param.put("api_type", "json"); ResponseEntity result = redditRestTemplate.postForEntity( "//oauth.reddit.com/api/new_captcha", req, String.class, param); String[] split = result.getBody().split("""); return split[split.length - 2]; }

4. Il modulo " Invia messaggio "

Successivamente, creiamo il modulo principale per inviare nuovi post a Reddit. L'invio di un collegamento richiede i seguenti dettagli:

  • titolo : il titolo dell'articolo
  • url : l'URL dell'articolo
  • subreddit - il sub-reddit a cui inviare il collegamento

Vediamo quindi come possiamo visualizzare questa semplice pagina di invio:

@RequestMapping("/post") public String showSubmissionForm(Model model) throws JsonProcessingException, IOException { String needsCaptchaResult = needsCaptcha(); if (needsCaptchaResult.equalsIgnoreCase("true")) { String iden = getNewCaptcha(); model.addAttribute("iden", iden); } return "submissionForm"; }

E ovviamente il submissionForm.html di base :

 Post   function submitPost(){ var data = {}; $('form').serializeArray().map(function(x){data[x.name] = x.value;}); $.ajax({ url: "api/posts", data: JSON.stringify(data), type: 'POST', contentType:'application/json' }).done(function(data) { if(data.length < 2){ alert(data[0]);} else{ window.location.href="submissionResponse?msg="+ data[0]+"&url="+data[1]; } }).fail(function(error) { alert(error.responseText); }); } 

5. Invia un collegamento a Reddit

Ora, diamo un'occhiata al passaggio finale: inviare il collegamento effettivo tramite l'API di Reddit.

Inoltreremo una richiesta di invio a Reddit utilizzando i parametri dal nostro modulo di submission :

@Controller @RequestMapping(value = "/api/posts") public class RedditPostRestController { @Autowired private RedditService service; @RequestMapping(method = RequestMethod.POST) @ResponseBody public List submit(@Valid @RequestBody PostDto postDto) { return service.submitPost(postDto); } }

Ecco l'implementazione effettiva del metodo:

public List submitPost(PostDto postDto) { MultiValueMap param1 = constructParams(postDto); JsonNode node = redditTemplate.submitPost(param1); return parseResponse(node); } private MultiValueMap constructParams(PostDto postDto) { MultiValueMap param = new LinkedMultiValueMap(); param.add("title", postDto.getTitle()); param.add("sr", postDto.getSubreddit()); param.add("url", postDto.getUrl()); param.add("iden", postDto.getIden()); param.add("captcha", postDto.getCaptcha()); if (postDto.isSendReplies()) { param.add("sendReplies", "true"); } param.add("api_type", "json"); param.add("kind", "link"); param.add("resubmit", "true"); param.add("then", "comments"); return param; }

E la semplice logica di analisi, gestendo la risposta dall'API di Reddit:

private List parseResponse(JsonNode node) { String result = ""; JsonNode errorNode = node.get("json").get("errors").get(0); if (errorNode != null) { for (JsonNode child : errorNode) null", "") + "

"; return Arrays.asList(result); } else { if ((node.get("json").get("data") != null) && (node.get("json").get("data").get("url") != null)) { return Arrays.asList("Post submitted successfully", node.get("json").get("data").get("url").asText()); } else { return Arrays.asList("Error Occurred while parsing Response"); } } }

Tutto questo funziona con un DTO di base :

public class PostDto { @NotNull private String title; @NotNull private String url; @NotNull private String subreddit; private boolean sendReplies; private String iden; private String captcha; }

Infine, submissionResponse.html :

Hello

Hello

Here

6. Conclusione

In questo breve tutorial abbiamo implementato alcune funzionalità di base di Invia a Reddit : semplicistiche ma completamente funzionali.

Nella parte successiva di questo case study, implementeremo nella nostra app una funzionalità Schedule Post for Later .

L' implementazione completa di questo tutorial può essere trovata nel progetto github: questo è un progetto basato su Eclipse, quindi dovrebbe essere facile da importare ed eseguire così com'è.

Fondo di sicurezza

Ho appena annunciato il nuovo corso Learn Spring Security, incluso il materiale completo incentrato sul nuovo stack OAuth2 in Spring Security 5:

>> SCOPRI IL RESTO DEL CORSO in basso

Ho appena annunciato il nuovo corso Learn Spring , incentrato sui fondamenti di Spring 5 e Spring Boot 2:

>> SCOPRI IL CORSO