Spring MVC sollicitatievragen

1. Inleiding

Spring MVC is het originele webframework van Spring, gebouwd op de Servlet API. Het biedt Model-View-Controller-architectuur die kan worden gebruikt om flexibele webtoepassingen te ontwikkelen.

In deze tutorial zullen we ons concentreren op de vragen die ermee verband houden, aangezien het vaak een onderwerp is in een sollicitatiegesprek met een Spring-ontwikkelaar.

Voor meer vragen over het Spring Framework kun je een ander Spring-gerelateerd artikel uit onze serie interviewvragen lezen.

2. Basic Spring MVC-vragen

V1. Waarom zouden we Spring MVC gebruiken?

Spring MVC implementeert een duidelijke scheiding van zorgen waardoor we onze applicaties eenvoudig kunnen ontwikkelen en testen.

De concepten als:

  • Verzender Servlet
  • Controllers
  • Bekijk resolvers
  • Weergaven, modellen
  • ModelAndView
  • Model- en sessiekenmerken

zijn volledig onafhankelijk van elkaar, en ze zijn maar voor één ding verantwoordelijk.

Daarom MVC geeft ons een behoorlijk grote flexibiliteit. Het is gebaseerd op interfaces (met meegeleverde implementatieklassen), en we kunnen elk onderdeel van het framework configureren door aangepaste interfaces te gebruiken.

Een ander belangrijk ding is dat we niet gebonden zijn aan een specifieke weergavetechnologie (bijvoorbeeld JSP), maar we hebben de mogelijkheid om te kiezen uit degene die we het leukst vinden.

Ook, we gebruiken Spring MVC niet alleen bij de ontwikkeling van webapplicaties, maar ook bij het creëren van RESTful webservices.

Q2. Wat is de rol van het @Autowired Annotatie?

De @Autowired annotatie kan worden gebruikt met velden of methoden voor het injecteren van een boon op type. Met deze annotatie kan Spring samenwerkende bonen oplossen en in uw boon injecteren.

Raadpleeg de tutorial over voor meer informatie @Autowired in de lente.

Q3. Leg een modelkenmerk uit

De @ModelAttribute annotatie is een van de belangrijkste annotaties in Spring MVC. Het bindt een methodeparameter of een method-retourwaarde aan een benoemd modelattribuut en stelt het vervolgens beschikbaar voor een webweergave.

Als we het op methodeniveau gebruiken, geeft dit aan dat het doel van die methode is om een ​​of meer modelattributen toe te voegen.

Aan de andere kant, wanneer het wordt gebruikt als een methode-argument, geeft het aan dat het argument uit het model moet worden opgehaald. Als het niet aanwezig is, moeten we het eerst instantiëren en vervolgens aan het model toevoegen. Eenmaal aanwezig in het model, moeten we de argumentenvelden invullen van alle verzoekparameters die overeenkomende namen hebben.

Meer over deze annotatie is te vinden in ons artikel met betrekking tot de @ModelAttribute annotatie.

V4. Leg het verschil uit tussen @Controller en @RestController?

Het belangrijkste verschil tussen de @Controller en @RestController annotaties is dat de @ResponseBody annotatie wordt automatisch opgenomen in het @RestController. Dit betekent dat we onze handlermethoden niet hoeven te annoteren met de @ResponseBody. We moeten dit doen in een @Controller class als we het reactietype rechtstreeks naar de HTTP-antwoordtekst willen schrijven.

V5. Beschrijf een PadVariabele

We kunnen de @PathVariable annotatie als een handlermethode-parameter om de waarde van een URI-sjabloonvariabele te extraheren.

Als we bijvoorbeeld een gebruiker op ID willen ophalen uit de www.mijnsite.com/gebruiker/123, moeten we onze methode in de controller in kaart brengen als /gebruikersnaam}:

@RequestMapping ("/ user / {id}") public String handleRequest (@PathVariable ("id") String userId, Model map) {}

De @PathVariable heeft slechts één element met de naam waarde. Het is optioneel en we gebruiken het om de variabelenaam van de URI-sjabloon te definiëren. Als we het waarde-element weglaten, moet de naam van de URI-sjabloonvariabele overeenkomen met de naam van de methode-parameter.

Het is ook toegestaan ​​om meerdere te hebben @PathVariable annotaties, ofwel door ze een voor een te declareren:

@RequestMapping ("/ user / {userId} / name / {userName}") public String handleRequest (@PathVariable String userId, @PathVariable String gebruikersnaam, modeltoewijzing) {}

of ze allemaal in een Kaart of MultiValueMap:

@RequestMapping ("/ user / {userId} / name / {userName}") public String handleRequest (@PathVariable Map varsMap, Model map) {}

V6. Validatie met behulp van Spring MVC

Spring MVC ondersteunt standaard JSR-303-specificaties. We moeten JSR-303 en zijn implementatie-afhankelijkheden toevoegen aan onze Spring MVC-applicatie. Hibernate Validator is bijvoorbeeld een van de JSR-303-implementaties die we tot onze beschikking hebben.

JSR-303 is een specificatie van de Java API voor bean-validatie, onderdeel van Jakarta EE en JavaSE, die ervoor zorgt dat eigenschappen van een bean aan specifieke criteria voldoen, met behulp van annotaties zoals @Niet nul, @Min, en @Max. Meer over validatie is beschikbaar in het artikel Java Bean Validation Basics.

De lente biedt de @Validator annotatie en de BindingResult klasse. De Validator implementatie leidt tot fouten in de behandelingsmethode van de controllerverzoek wanneer we ongeldige gegevens hebben. Dan kunnen we de BindingResult class om die fouten te krijgen.

Naast het gebruik van de bestaande implementaties, kunnen we er zelf een maken. Om dit te doen, maken we eerst een annotatie die voldoet aan de JSR-303-specificaties. Vervolgens implementeren we het Validator klasse. Een andere manier zou zijn om Spring's te implementeren Validator interface en stel deze in als validator via @InitBinder annotatie in Controller klasse.

Raadpleeg de tutorial over aangepaste validatie in Spring MVC om te zien hoe u uw eigen validaties kunt implementeren en gebruiken.

V7. Wat zijn de @RequestBody en de @ResponseBody?

De @RequestBody annotatie, gebruikt als een handlermethode-parameter, bindt de hoofdtekst van het HTTP-verzoek aan een overdrachts- of domeinobject. Spring deserialiseert automatisch inkomende HTTP-verzoeken naar het Java-object met behulp van Http Message Converters.

Wanneer we de @ResponseBody annotatie op een handlermethode in de Spring MVC-controller, geeft dit aan dat we het retourtype van de methode rechtstreeks naar de HTTP-antwoordtekst zullen schrijven. We stoppen het niet in een Model, en Spring zal niet worden geïnterpreteerd als een weergavenaam.

Lees het artikel over @RequestBody en @ResponseBody voor meer details over deze annotaties.

V8. Leg uit Model, ModelMap en ModelAndView?

De Model interface definieert een houder voor modelattributen. De ModelMap heeft een soortgelijk doel, met de mogelijkheid om een ​​verzameling waarden door te geven. Vervolgens worden die waarden behandeld alsof ze binnen een Kaart. We moeten opmerken dat in Model (ModelMap) kunnen we alleen gegevens opslaan. We plaatsen gegevens in en retourneren een weergavenaam.

Aan de andere kant, met de ModelAndView, retourneren we het object zelf. We zetten alle vereiste informatie, zoals de gegevens en de weergavenaam, in het object dat we retourneren.

U kunt meer informatie vinden in het artikel op Model, ModelMap, en ModelView.

V9. Leg uit SessionAttributes en SessionAttribute

De @SessionAttributes annotatie wordt gebruikt voor het opslaan van het modelattribuut in de sessie van de gebruiker. We gebruiken het op het niveau van de controllerklasse, zoals weergegeven in ons artikel over de sessiekenmerken in Spring MVC:

@Controller @RequestMapping ("/ sessionattributes") @SessionAttributes ("todos") openbare klasse TodoControllerWithSessionAttributes {@GetMapping ("/ form") public String showForm (Modelmodel, @ModelAttribute ("todos") TodoList todos) {// method body return "sessionattributesform"; } // andere methodes }

In het vorige voorbeeld is het modelkenmerk ‘todos‘Wordt aan de sessie toegevoegd als het @ModelAttribute en de @SessionAttributes hebben hetzelfde naamkenmerk.

Als we het bestaande attribuut willen ophalen uit een sessie die wereldwijd wordt beheerd, gebruiken we @SessionAttribute annotatie als een methodeparameter:

@GetMapping openbare String getTodos (@SessionAttribute ("todos") TodoList todos) {// methode body return "todoView"; }

V10. Wat is het doel van @EnableWebMVC?

De @EnableWebMvc Het doel van annotatie is om Spring MVC in te schakelen via Java-configuratie. Het is gelijk aan in een XML-configuratie. Deze annotatie importeert Spring MVC-configuratie van WebMvcConfigurationSupport. Het maakt ondersteuning mogelijk voor @Controller-geannoteerde klassen die @RequestMapping om inkomende verzoeken toe te wijzen aan een handlermethode.

U kunt meer over deze en soortgelijke annotaties lezen in onze Gids voor de lente @Inschakelen Annotaties.

V11. Wat is ViewResolver in de lente?

De ViewResolver stelt een applicatie in staat om modellen in de browser weer te geven - zonder de implementatie te koppelen aan een specifieke weergavetechnologie - door weergavenamen toe te wijzen aan werkelijke weergaven.

Voor meer informatie over het ViewResolver, bekijk dan onze Gids voor de ViewResolver in Spring MVC.

V12. Wat is de BindingResult?

BindingResult is een interface van org.springframework.validation pakket dat bindende resultaten vertegenwoordigt. We kunnen het gebruiken om fouten in het ingediende formulier op te sporen en te rapporteren. Het is gemakkelijk aan te roepen - we moeten er alleen voor zorgen dat we het als een parameter plaatsen direct na het formulierobject dat we valideren. Het optionele Model parameter moet komen na de BindingResult, zoals te zien is in de zelfstudie voor aangepaste validatie:

@PostMapping ("/ user") public String submitForm (@Valid NewUserForm newUserForm, BindingResult resultaat, Modelmodel) {if (result.hasErrors ()) {return "userHome"; } model.addAttribute ("bericht", "Geldige vorm"); retourneer "userHome"; }

Wanneer de lente de @Geldig annotatie, zal het eerst proberen de validator te vinden voor het object dat wordt gevalideerd. Vervolgens pikt het de validatie-annotaties op en roept het de validator aan. Ten slotte worden gevonden fouten in het BindingResult en voeg de laatste toe aan het weergavemodel.

V13. Wat is een formulierondersteunend object?

Het formulierondersteunende object of een opdrachtobject is slechts een POJO die gegevens verzamelt van het formulier dat we indienen.

We moeten in gedachten houden dat het geen logica bevat, alleen gegevens.

Raadpleeg ons artikel over Formulieren in Spring MVC voor meer informatie over het gebruik van formulierondersteuningsobjecten met de formulieren in Spring MVC.

V14. Wat is de rol van het @Kwalificatie Annotatie?

Het wordt gelijktijdig gebruikt met de @Autowired annotatie om verwarring te voorkomen wanneer er meerdere exemplaren van een bonentype aanwezig zijn.

Laten we een voorbeeld bekijken. We hebben twee vergelijkbare bonen in XML-configuratie gedeclareerd:

Als we de boon proberen te bedraden, krijgen we een org.springframework.beans.factory.NoSuchBeanDefinitionException. Om het probleem op te lossen, moeten we @Kwalificatie om Spring te vertellen welke boon moet worden bedraad:

@Autowired @Qualifier ("person1") privé Persoon persoon;

V15. Wat is de rol van het @Verplicht Annotatie?

De @Verplicht annotatie wordt gebruikt op setter-methoden en geeft aan dat de bean-eigenschap met deze annotatie moet worden ingevuld tijdens de configuratie. Anders gooit de Spring-container een BeanInitializationException uitzondering.

Ook, @Verplicht is anders dan @Autowired - aangezien het beperkt is tot een setter, terwijl @Autowired is niet. @Autowired kan ook worden gebruikt om te bedraden met een constructor en een veld, while @Verplicht controleert alleen of de eigenschap is ingesteld.

Laten we een voorbeeld bekijken:

openbare klasse Persoon {privé Stringnaam; @Required public void setName (String name) {this.name = name; }}

Nu de naam van de Persoon bean moet als volgt in XML-configuratie worden ingesteld:

Houd er rekening mee dat @Verplicht werkt niet met op Java gebaseerde @Configuratie klassen standaard. Als u ervoor moet zorgen dat al uw eigenschappen zijn ingesteld, kunt u dit doen wanneer u de boon in de @Boon geannoteerde methoden.

V16. Beschrijf het patroon van de frontcontroller

In het Front Controller-patroon gaan alle verzoeken eerst naar de frontcontroller in plaats van naar de servlet. Het zorgt ervoor dat de reacties klaar zijn en stuurt ze terug naar de browser. Op deze manier hebben we één plek waar we controle hebben over alles wat van de buitenwereld komt.

De voorste controller identificeert de servlet die het verzoek als eerste moet afhandelen. Als het vervolgens de gegevens van de servlet terugkrijgt, zal het beslissen welke weergave moet worden weergegeven en ten slotte zal het de weergegeven weergave terugsturen als een reactie:

Raadpleeg onze Guide to the Front Controller Pattern in Java om de implementatiedetails te zien.

V17. Wat zijn model 1- en model 2-architecturen?

Model 1 en Model 2 vertegenwoordigen twee veelgebruikte ontwerpmodellen als het gaat om het ontwerpen van Java-webapplicaties.

In Model 1 komt een verzoek binnen bij een servlet of JSP waar het wordt afgehandeld. De servlet of de JSP verwerkt het verzoek, verwerkt bedrijfslogica, haalt en valideert gegevens en genereert het antwoord:

Omdat deze architectuur eenvoudig te implementeren is, gebruiken we deze meestal in kleine en eenvoudige applicaties.

Aan de andere kant is het niet handig voor grootschalige webapplicaties. De functionaliteiten worden vaak gedupliceerd in JSP's waar bedrijfs- en presentatielogica aan elkaar gekoppeld zijn.

Model 2 is gebaseerd op het ontwerppatroon van de Model View Controller en scheidt de weergave van de logica die de inhoud manipuleert.

Verder kunnen we in het MVC-patroon drie modules onderscheiden: het model, de weergave en de controller. Het model vertegenwoordigt de dynamische datastructuur van een applicatie. Het is verantwoordelijk voor de manipulatie van gegevens en bedrijfslogica. De weergave is verantwoordelijk voor het weergeven van de gegevens, terwijl de controller dient als een interface tussen de vorige twee.

In Model 2 wordt een verzoek doorgegeven aan de controller, die de vereiste logica afhandelt om de juiste inhoud te krijgen die moet worden weergegeven. De controller plaatst vervolgens de inhoud terug in het verzoek, meestal als een JavaBean of een POJO. Het beslist ook welke weergave de inhoud moet weergeven en geeft uiteindelijk het verzoek door. Vervolgens geeft de weergave de gegevens weer:

3. Geavanceerde Spring MVC-vragen

V18. Wat is het verschil tussen @Controller, @Component, @Repository, en @Onderhoud Annotaties in het voorjaar?

Volgens de officiële Spring-documentatie, @Component is een generiek stereotype voor elk onderdeel dat door Spring wordt beheerd. @Repository, @Onderhoud, en @Controller zijn specialisaties van @Component voor meer specifieke use-cases, bijvoorbeeld in respectievelijk de persistentie-, service- en presentatielaag.

Laten we eens kijken naar specifieke gebruiksscenario's van de laatste drie:

  • @Controller - geeft aan dat de klasse de rol van controller vervult, en detecteert @RequestMapping annotaties binnen de klas
  • @Onderhoud - geeft aan dat de klasse bedrijfslogica bevat en methoden aanroept in de repositorylaag
  • @Opslagplaats - geeft aan dat de klasse een gegevensrepository definieert; het is zijn taak om platformspecifieke uitzonderingen op te vangen en ze opnieuw te werpen als een van de verenigde ongecontroleerde uitzonderingen van Spring

V19. Wat zijn DispatcherServlet en ContextLoaderListener?

Simpel gezegd, in het ontwerppatroon van de Front Controller is een enkele controller verantwoordelijk voor het sturen van inkomende HttpRequests aan alle andere controllers en handlers van een applicatie.

Lente DispatcherServlet implementeert dit patroon en is daarom verantwoordelijk voor het correct coördineren van het HttpRequests naar de juiste handlers.

Aan de andere kant, ContextLoaderListener start en sluit Spring's root af WebApplicationContext. Het verbindt de levenscyclus van ApplicationContext naar de levenscyclus van de ServletContext. We kunnen het gebruiken om gedeelde bonen te definiëren die in verschillende Spring-contexten werken.

Voor meer details over DispatcherServletverwijzen wij u naar deze tutorial.

V20. Wat is een MultipartResolver en wanneer moeten we het gebruiken?

De MultipartResolver interface wordt gebruikt voor het uploaden van bestanden. Het Spring-raamwerk biedt er een MultipartResolver implementatie voor gebruik met Commons FileUpload en een andere voor gebruik met Servlet 3.0 multipart request parsing.

Hiermee kunnen we bestandsuploads in onze webapplicaties ondersteunen.

V21. Wat is Spring MVC Interceptor en hoe te gebruiken?

Met Spring MVC Interceptors kunnen we een verzoek van een klant onderscheppen en het op drie plaatsen verwerken - vóór afhandeling, na afhandeling of na voltooiing (wanneer de weergave wordt weergegeven) van een verzoek.

De interceptor kan worden gebruikt voor transversale problemen en om repetitieve handlercode zoals logboekregistratie, het wijzigen van wereldwijd gebruikte parameters in het Spring-model, enz. Te vermijden.

Voor details en verschillende implementaties, bekijk het artikel Inleiding tot Spring MVC HandlerInterceptor.

V22. Wat is een Init Binder?

Een methode geannoteerd met @InitBinder wordt gebruikt om een ​​verzoekparameter, URI-sjabloon en ondersteunings- / opdrachtobjecten aan te passen. We definiëren het in een controller en het helpt bij het beheersen van het verzoek. Bij deze methode registreren en configureren we onze custom PropertyEditors, een formatter en validators.

De annotatie heeft de ‘waarde‘Element. Als we het niet instellen, is de @InitBinder geannoteerde methoden worden aangeroepen bij elk HTTP-verzoek. Als we de waarde instellen, worden de methoden alleen toegepast voor bepaalde commando- / formulierattributen en / of verzoekparameters waarvan de namen overeenkomen met de ‘waarde‘Element.

Het is belangrijk om te onthouden dat een van de argumenten moet zijn WebDataBinder. Andere argumenten kunnen van elk type zijn dat door handlermethoden wordt ondersteund, met uitzondering van opdracht- / formulierobjecten en bijbehorende validatieresultaatobjecten.

V23. Leg het advies van een controller uit

De @ControllerAdvice annotatie stelt ons in staat om globale code te schrijven die van toepassing is op een breed scala aan controllers. We kunnen de reeks controllers koppelen aan een gekozen pakket of een specifieke annotatie.

Standaard, @ControllerAdvice is van toepassing op de klassen die zijn geannoteerd met @Controller (of @RestController). We hebben ook een paar eigenschappen die we gebruiken als we specifieker willen zijn.

Als we toepasselijke klassen tot een pakket willen beperken, moeten we de naam van het pakket aan de annotatie toevoegen:

@ControllerAdvice ("my.package") @ControllerAdvice (value = "my.package") @ControllerAdvice (basePackages = "my.package")

Het is ook mogelijk om meerdere pakketten te gebruiken, maar deze keer moeten we een array gebruiken in plaats van de Draad.

Behalve door de naam van het pakket te beperken, kunnen we het doen door een van de klassen of interfaces van dat pakket te gebruiken:

@ControllerAdvice (basePackageClasses = MyClass.class)

De 'toewijsbareTypes‘Element past het @ControllerAdvice naar de specifieke klassen, terwijl ‘annotaties‘Doet het voor bepaalde annotaties.

Het is opmerkelijk om te onthouden dat we het samen met moeten gebruiken @BuienRadarNL. Deze combinatie stelt ons in staat om een ​​globaal en meer specifiek foutafhandelingsmechanisme te configureren zonder dat dit elke keer voor elke controllerklasse moet worden geïmplementeerd.

V24. Wat doet de @BuienRadarNL Annotatie doen?

De @BuienRadarNL annotatie stelt ons in staat om een ​​methode te definiëren die de uitzonderingen zal behandelen. We kunnen de annotatie onafhankelijk gebruiken, maar het is een veel betere optie om deze samen met de @ControllerAdvice. Zo kunnen we een globaal foutafhandelingsmechanisme opzetten. Op deze manier hoeven we niet de code te schrijven voor de afhandeling van uitzonderingen binnen elke controller.

Laten we eens kijken naar het voorbeeld uit ons artikel over foutafhandeling voor REST met Spring:

@ControllerAdvice openbare klasse RestResponseEntityExceptionHandler breidt ResponseEntityExceptionHandler {@ExceptionHandler (waarde = {IllegalArgumentException.class, IllegalStateException.class}) beschermd ResponseEntity handleConflict (RuntimeException ex, WebRequest-verzoek moet toepassingsspecifiek zijn "; return handleExceptionInternal (ex, bodyOfResponse, nieuwe HttpHeaders (), HttpStatus.CONFLICT, verzoek); }}

We moeten ook opmerken dat dit zal zorgen @BuienRadarNL methoden voor alle controllers die gooien IllegalArgumentException of IllegalStateException. De uitzonderingen verklaard met @BuienRadarNL moet overeenkomen met de uitzondering die wordt gebruikt als het argument van de methode. Anders mislukt het mechanisme voor het oplossen van uitzonderingen tijdens runtime.

Een ding om in gedachten te houden is dat het mogelijk is om er meer dan één te definiëren @BuienRadarNL voor dezelfde uitzondering. We kunnen het echter niet in dezelfde klas doen, omdat Spring zou klagen door een uitzondering te maken en niet te starten bij het opstarten.

Aan de andere kant, als we die in twee afzonderlijke klassen definiëren, zal de applicatie starten, maar het zal de eerste handler gebruiken die het vindt, mogelijk de verkeerde.

V25. Afhandeling van uitzonderingen in webtoepassingen

We hebben drie opties voor het afhandelen van uitzonderingen in Spring MVC:

  • per uitzondering
  • per controller
  • wereldwijd

Als er een onverwerkte uitzondering wordt gegenereerd tijdens de verwerking van webverzoeken, retourneert de server een HTTP 500-antwoord. Om dit te voorkomen, we moeten al onze aangepaste uitzonderingen annoteren met de @ResponseStatus annotatie. Dit soort uitzonderingen wordt opgelost door HandlerExceptionResolver.

Dit zorgt ervoor dat de server een passend HTTP-antwoord retourneert met de opgegeven statuscode wanneer een controllermethode onze uitzondering genereert. We moeten in gedachten houden dat we onze uitzondering niet ergens anders moeten behandelen om deze aanpak te laten werken.

Een andere manier om met de uitzonderingen om te gaan, is door de @BuienRadarNL annotatie. We voegen toe @BuienRadarNL methoden naar elke controller en gebruik deze om de uitzonderingen die van binnenuit die controller worden gegenereerd af te handelen. Deze methoden kunnen uitzonderingen verwerken zonder de @ResponseStatus annotatie, stuur de gebruiker door naar een speciale foutweergave of stel een volledig aangepaste foutreactie samen.

We kunnen ook de servlet-gerelateerde objecten (HttpServletRequest, HttpServletResponse, HttpSession, en Opdrachtgever) als de parameters van de handlermethoden. Maar we moeten niet vergeten dat we de Model object als parameter rechtstreeks.

De derde optie voor het afhandelen van fouten is door @ControllerAdvice klassen. Het stelt ons in staat dezelfde technieken toe te passen, alleen deze keer op applicatieniveau en niet alleen op de specifieke controller. Om dit mogelijk te maken, moeten we de @ControllerAdvice en de @BuienRadarNL samen. Op deze manier behandelen exception handlers de uitzonderingen die door een controller worden gegenereerd.

Raadpleeg het artikel Foutafhandeling voor REST met Spring voor meer informatie over dit onderwerp.

4. Conclusie

In dit artikel hebben we enkele van de Spring MVC-gerelateerde vragen onderzocht die naar voren kunnen komen tijdens het technische interview voor Spring-ontwikkelaars. Met deze vragen dient u rekening te houden als uitgangspunt voor verder onderzoek, aangezien dit geen uitputtende lijst is.

We wensen je veel succes bij de komende interviews!