Opret et link til Reddit API

Sikkerhedstop

Jeg annoncerede netop det nye Learn Spring Security-kursus, inklusive det fulde materiale med fokus på den nye OAuth2-stak i Spring Security 5:

>> KONTROLLER KURSEN REST Top

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN

1. Oversigt

I denne anden artikel i serien opbygger vi nogle enkle funktioner til at sende på Reddit fra vores applikation via deres API.

2. Nødvendig sikkerhed

Først - lad os fjerne sikkerhedsaspektet.

For at Indsend et link til Reddit, skal vi definere en OAuth-beskyttet ressource med rækkevidde af “Indsend“:

@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 ("identitet", "indsende")); details.setGrantType ("autorisationskode"); returnere detaljer; }

Bemærk, at vi også specificerer rækkeviddeidentitet”Fordi vi også har brug for adgang til brugerkontooplysningerne.

3. Er Captcha påkrævet?

Brugere, der er nye for Reddit skal udfylde en Captcha for at indsende det er før de passerer en bestemt karma-tærskel inden for Reddit.

For disse brugere skal vi først kontrollere, om Captcha er nødvendig:

private String needsCaptcha () {String result = redditRestTemplate.getForObject ("//oauth.reddit.com/api/needs_captcha.json", String.class); returresultat } privat streng getNewCaptcha () {HttpHeaders headers = nye HttpHeaders (); headers.setContentType (MediaType.APPLICATION_JSON); HttpEntity req = ny HttpEntity (overskrifter); Kortparameter = nyt HashMap (); param.put ("api_type", "json"); ResponseEntity-resultat = redditRestTemplate.postForEntity ("//oauth.reddit.com/api/new_captcha", req, String.class, param); String [] split = result.getBody (). Split ("" "); return split [split.length - 2];}

4. "Send indlæg" Form

Lad os derefter oprette hovedformularen til indsendelse af nye indlæg til Reddit. Indsendelse af et link kræver følgende detaljer:

  • titel - titlen på artiklen
  • url - webadressen til artiklen
  • subreddit - den underreddit, som linket skal sendes til

Så lad os se, hvordan vi kan vise denne enkle indsendelsesside:

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

Og selvfølgelig det grundlæggende submissionForm.html:

 Indlægsfunktion submitPost () {var data = {}; $ ('form'). serializeArray (). kort (funktion (x) {data [x.navn] = x.værdi;}); $ .ajax ({url: "api / posts", data: JSON.stringify (data), type: 'POST', contentType: 'application / json'}). udført (funktion (data) {if (data.length) <2) {alarm (data [0]);} andet {window.location.href = "submissionResponse? Msg =" + data [0] + "& url =" + data [1];}}. Mislykkedes (funktion (fejl) {alarm (error.responseText);}); } 

5. Indsend et link til Reddit

Lad os nu se på det sidste trin - indsende det aktuelle link via Reddit API.

Vi POSTER en indsendelsesanmodning til Reddit ved hjælp af parametrene fra vores submissionForm:

@Controller @RequestMapping (værdi = "/ api / indlæg") offentlig klasse RedditPostRestController {@Autowired privat RedditService-tjeneste; @RequestMapping (metode = RequestMethod.POST) @ResponseBody offentlig Liste indsend (@Valid @RequestBody PostDto postDto) {return service.submitPost (postDto); }}

Her er den egentlige metodeimplementering:

offentlig liste submitPost (PostDto postDto) {MultiValueMap param1 = constructParams (postDto); JsonNode-node = redditTemplate.submitPost (param1); returner parseResponse (node); } privat MultiValueMap constructParams (PostDto postDto) {MultiValueMap param = ny 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 ()); hvis (postDto.isSendReplies ()) {param.add ("sendReplies", "true"); } param.add ("api_type", "json"); param.add ("kind", "link"); param.add ("resubmit", "true"); param.add ("derefter", "kommentarer"); returner param; }

Og den enkle parselogik, håndtering af svaret fra Reddit API:

privat liste parseResponse (JsonNode node) {String result = ""; JsonNode errorNode = node.get ("json"). Get ("fejl"). Get (0); hvis (errorNode! = null) {for (JsonNode-barn: errorNode) null "," ") +"

"; returner Arrays.asList (resultat);} ellers {if ((node.get (" json "). get (" data ")! = null) && (node.get (" json "). get (" data ") .get (" url ")! = null)) {return Arrays.asList (" Indlæg sendt med succes ", node.get (" json "). get (" data "). get (" url "). asText ());} andet {return Arrays.asList ("Der opstod en fejl under parsing af svar");}}

Alt dette arbejder med en grundlæggende DTO:

offentlig klasse PostDto {@NotNull privat streng titel; @NotNull privat String url; @NotNull privat streng subreddit; private boolske sendRespies; private String iden; private String captcha; }

Endelig - den submissionResponse.html:

Hej

Hej

Her

6. Konklusion

I denne hurtige vejledning implementerede vi nogle grundlæggende Send til Reddit funktionalitet - forenklet, men fuldt funktionel.

I den næste del af denne casestudie implementerer vi en Planlæg post for senere funktionalitet i vores app.

Det fuld implementering af denne vejledning kan findes i github-projektet - dette er et Eclipse-baseret projekt, så det skal være let at importere og køre som det er.

Sikkerhedsbund

Jeg annoncerede netop det nye Learn Spring Security-kursus, inklusive det fulde materiale med fokus på den nye OAuth2-stak i Spring Security 5:

>> KONTROLLER KURSEN REST bunden

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN