Публикувайте връзка към API на Reddit

Защита отгоре

Току-що обявих новия курс Learn Spring Security, включително пълния материал, фокусиран върху новия стек OAuth2 в Spring Security 5:

>> ПРЕГЛЕД НА ОСТАНАЛИТЕ НА КУРСА Горе

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА

1. Общ преглед

В тази втора статия от поредицата ще изградим някои прости функции, които да публикуваме в Reddit от нашето приложение, чрез техния API.

2. Необходима сигурност

Първо - нека махнем аспекта на сигурността.

За да изпратим връзка към Reddit , трябва да дефинираме ресурс, защитен от OAuth с обхвата на „ submit “:

@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; }

Обърнете внимание, че ние също посочваме обхватаидентичност “, тъй като също се нуждаем от достъп до информацията за потребителския акаунт.

3. Необходима ли е капча?

Потребителите, които са нови в Reddit, трябва да попълнят Captcha, за да подадат; това е преди да преминат определен праг на карма в Reddit.

За тези потребители първо трябва да проверим дали е необходима 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. Формулярът „ Изпращане на пощата

След това нека създадем основния формуляр за изпращане на нови публикации в Reddit. Изпращането на връзка изисква следните подробности:

  • заглавие - заглавието на статията
  • url - URL адресът на статията
  • subreddit - подредитът, към който се изпраща връзката

Така че нека видим как можем да покажем тази проста страница за изпращане:

@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"; }

И разбира се основното представянеForm.html :

 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. Изпратете линк към Reddit

Сега - нека да разгледаме последната стъпка - изпращане на действителната връзка чрез Reddit API.

Ще публикуваме заявка за изпращане до Reddit, като използваме параметрите от нашата форма за подаване :

@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); } }

Ето действителното изпълнение на метода:

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; }

И простата логика за разбор, обработваща отговора от Reddit API:

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"); } } }

Всичко това работи с основен DTO :

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

И накрая - submitResponse.html :

Hello

Hello

Here

6. Заключение

В този бърз урок внедрихме някои основни функционалности Submit to Reddit - опростени, но напълно функционални.

В следващата част от това казус ще внедрим в нашето приложение функционалност Schedule Post за по-късно .

Най- пълното прилагане на този урок може да се намери в проекта GitHub - това е Eclipse проект на базата, така че трябва да бъде лесен за внос и работи като такъв.

Сигурност отдолу

Току-що обявих новия курс Learn Spring Security, включително пълния материал, фокусиран върху новия стек OAuth2 в Spring Security 5:

>> ПРОВЕТЕТЕ ОСТАНАЛИТЕ НА КУРСА отдолу

Току що обявих новия курс Learn Spring , фокусиран върху основите на Spring 5 и Spring Boot 2:

>> ПРЕГЛЕД НА КУРСА