Você pode usar este artigo para entender como usar o Spring MVC para criar sites ou serviços RESTful. Além disso, obtenha uma visão geral das perguntas freqüentes sobre as tarefas mais comuns do Spring MVC.
Nota: um artigo com ~ 7.500 palavras provavelmente não vale a pena ler em um dispositivo móvel. Marque-o como favorito e volte mais tarde.
Conteúdo
Introdução
O que é o Spring MVC?
Spring MVC — - Spring. - RESTful (, JSON/XML) Spring, , REST Spring Boot .
, ?
, : .
( , Spring Spring Boot, , Spring Framework?)
HttpServlets 101
- Java Spring (MVC/Boot) , :
- HTML → - HTML-, .
- JSON/XML → - RESTful, JSON XML. Javascript - , .
- , , .
- ? Java?
- Java HttpServlets. HTML, JSON XML. , 1 - Java (Spring MVC, Wicket, Struts) HttpServlets.
( : HttpServlets, .)
HTML- HttpServlets
HttpServlet, HTML-.
package com.marcobehler.springmvcarticle;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServletV1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
if (req.getRequestURI().equals("/")) {
resp.setContentType("text/html");
resp.getWriter().print("<html><head></head><body><h1>Welcome!</h1><p>This is a very cool page!</p></body></html>");
}
else {
throw new IllegalStateException("Help, I don't know what to do with this url");
}
}
}
.
public class MyServletV1 extends HttpServlet {
Java HttpServlet.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
() GET, doGet () . POST doPost (). HTTP .
if (req.getRequestURI().equals("/")) {
, URL- , . «/», www.marcobehler.com, www.marcobehler.com/hello.
resp.setContentType("text/html");
ServletResponse, , . HTML.
resp.getWriter().print("<html><head></head><body><h1>Welcome!</h1><p>This is a very cool page!</p></body></html>");
: - — HTML! HTML- ServletResponse. response writer.
, Tomcat Jetty. , , , :
package com.marcobehler.springmvcarticle;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
public class TomcatApplicationLauncher {
public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.getConnector();
Context ctx = tomcat.addContext("", null);
Wrapper servlet = Tomcat.addServlet(ctx, "myServlet", new MyServletV2());
servlet.setLoadOnStartup(1);
servlet.addMapping("/*");
tomcat.start();
}
}
.
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.getConnector();
Tomcat, 8080.
Context ctx = tomcat.addContext("", null);
Wrapper servlet = Tomcat.addServlet(ctx, "myServlet", new MyServletV2());
Tomcat. , Tomcat .
servlet.addMapping("/*");
Tomcat, , . /* , (/users, /register, /checkout).
tomcat.start();
. main(), 8080 - (http://localhost:8080 /), HTML.
, , doGet () doPost (), - . .
JSON HttpServlets
, ( ) HTML- REST API . React AngularJS URL- :
/api/users/{userId}
JSON userId. MyServlet , , - ?
package com.marcobehler.springmvcarticle;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyServletV2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
if (req.getRequestURI().equals("/")) {
resp.setContentType("text/html");
resp.getWriter().print("<html><head></head><body><h1>Welcome!</h1><p>This is a very cool page!</p></body></html>");
} else if (req.getRequestURI().startsWith("/api/users/")) {
Integer prettyFragileUserId = Integer.valueOf(req.getRequestURI().lastIndexOf("/") + 1);
resp.setContentType("application/json");
resp.getWriter().print("{\n" +
" \"id\":" + prettyFragileUserId + ",\n" +
" \"age\": 55,\n" +
" \"name\" : \"John Doe\"\n" +
"}");
} else {
throw new IllegalStateException("Help, I don't know what to do with this url");
}
}
}
.
} else if (req.getRequestURI().startsWith("/api/users/")) {
if doGet /api/users/.
Integer prettyFragileUserId = Integer.valueOf(req.getRequestURI().lastIndexOf("/") + 1);
URL. URL — userID, , 5 /api/users/5. , int, !
resp.setContentType("application/json");
JSON .
resp.getWriter().print("{\n" +
" \"id\":" + prettyFragileUserId + ",\n" +
" \"age\": 55,\n" +
" \"name\" : \"John Doe\"\n" +
"}");
, JSON — , HTTPServletResponse. , JSON Java- , .
« »
, :
- HTTP- , URI , .. : .
- , . : , . , .
- JSON HTML .
, ? , ? URI , JSON, ?
Spring MVC.
DispatcherServlet
Spring MVC , Model-View-Controller. .
, Spring MVC — , -?
DispatcherServlet.
( , , , )
Spring MVC DispatcherServlet?
, - Java , Spring MVC , HTTP- ( DispatcherServlet -).
HTTP-, ? « », HTML .
DispatcherServlet :
- URI HTTP . : POST /register?name=john&age33.
- (/ ) Java REST ,, .
- , .. , , , , .
- HTML/JSON/XML.
, , DispatcherServlet .

. ModelAndView ? DispatcherServlet ?
Let's-write-HTML? .
— HTML
, HTML , Spring MVC ( Spring Boot), . .
Spring
(POST/register?name=john&age33) .
package com.marcobehler.springmvcarticle;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class RegistrationController {
@PostMapping("/register")
public String registerUser(@RequestParam(required = false) Integer age, @RequestParam String name, Model model) {
User user = new User(name, age);
model.addAttribute("user", user);
return "registration-success";
}
}
.
@Controller
public class RegistrationController {
Spring Controller, .
@PostMapping("/register")
DispatcherServlet, , POST /register, (, ?Username=), .
public String registerUser(@RequestParam(required = false) Integer age, @RequestParam String name, Model model) {
, .
, , URL (?age=10&name=Joe), POST. , name ( age )
age, , Integer ( , Integer)
, , Spring MVC model . , , HTML-, .
User user = new User(name, age);
, . , , . -.
model.addAttribute("user", user);
«user». , HTML- , , «${user.name}». .
return "registration-success";
registration-success. , , .. HTML, , Spring .
Views ()
, (, , ) Spring MVC , .. , , registration-success.html.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p th:text="'Hello ' + ${user.name} + '!'"></p>
</body>
</html>
HTML-, . , .
<p th:text="'Hello ' + ${user.name} + '!'"></p>
, th:text=? Spring? - ?
: Spring MVC HTML. HTML- , , .
Thymeleaf, Spring MVC.
Spring MVC
, Spring MVC, : Thymeleaf, Velocity, Freemarker, Mustache JSP ( ).
, , , , HTML- — , .
, , , . , ?
ViewResolver?
, Spring HTML-, .
, , ViewResolver. , , Spring ViewResolvers , . ViewResolvers, .
, Thymeleaf. , ThymeleafViewResolver.
package com.marcobehler.springmvcarticle;
import org.springframework.context.annotation.Bean;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
public class ThymeleafConfig {
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("classpath:/templates");
templateResolver.setSuffix(".html");
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
.
@Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
, ThymeleafViewResolver Spring ViewResolver. (: registration-success), ViewResolvers .
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
ThymeleafViewResolver Thymeleaf . SpringResourceTemplateResolver. .
SpringResourceTemplateResolver Thymeleaf
templateResolver.setPrefix("classpath:/templates");
templateResolver.setSuffix(".html");
, ( Spring Resources): « classpath, /templates». .html. :
, String, registration-success, ThymeleafViewResolver : classpath:/templates/registration-success.html.
: Spring Boot
: , ViewResolver, Spring Boot. . Spring Boot , , spring-boot-starter-thymeleaf.
ViewResolver , src/main/resources/template.
, Spring Boot Spring MVC . .
: Model-View-Controller
Controller & ViewResolver, Spring Model-View-Controller.
- (Controller, @PostMapping, @RequestParam) , .
- ( ), . , .
- — HTML. , (). HTTP-. HTTP- .
.
, , Spring , HTTP, - .
, Spring MVC HTTP.
, HTTP-.
@GetMapping @RequestMappping
@GetMapping . *@RequestMapping*
. :
@GetMapping("/books")
public void book() {
}
@RequestMapping(value = "/books", method = RequestMethod.GET)
public void book2() {
}
@GetMapping, @[Post|Put|Delete|Patch]Mapping @RequestMapping(method=XXX). (Spring 4.3+) () URL, , @RequestMapping , Spring.
@RequestParam
HTTP-, URL (?Key=value) , @RequestParam.
, (, HTTP String int), .
@PostMapping("/users")
public User createUser(@RequestParam(required = false) Integer age, @RequestParam String name) {
}
, 400 Bad Request , Spring Boot, , :
{"timestamp":"2020-04-26T08:34:34.441+0000","status":400,"error":"Bad Request","message":"Required Integer parameter 'age' is not present","path":"/users"}
, Spring @RequestParams - . " ".
, getter/setter.
@PostMapping("/users")
public User createUser(UserDto userDto) {
}
@PathVariable
, URI , @PathVariable. , userId=123, URL: GET / users/123
- , {} .
, PathVariables .
@GetMapping("/users/{userId}")
public User getUser(@PathVariable(required = false) String userId) {
return user;
}
PathVariables, , Java- ( , getter/setter).
@GetMapping("/users/{userId}")
public User getUser(UserDto userDto) {
return user;
}
:
, HTML- Spring MVC :
- , "" . Spring , ( , ) .
- , . .
- , HTML , .
- , , Spring , HTML- .
- , , , Spring Boot , .
.
REST — XML/JSON
RESTFul , -. , -, () JSON XML. , , JSON, , JSON.
, JSON HTTP-.
POST http://localhost:8080/users
{"email": "angela@merkel.de"}
Java ( Spring MVC) JSON . , , . Java, Spring JSON.
public class UserDto {
private String email;
}
, , HTML . RESTful , HTML , JSON.
HTTP → Java Java → HTTP .
, , Spring MVC REST .
REST
, XML/JSON, @RestController Controller. ( @RestController Controller, . FAQ ).
REST- , , :
package com.marcobehler.springmvcarticle;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List;
@RestController
public class BankController {
@GetMapping("/transactions/{userId}")
public List<Transaction> transactions(String userId) {
List<Transaction> transactions = Collections.emptyList();
return transactions;
}
}
.
@RestController
public class BankController {
BankController @RestController, Spring, HTML- ModelAndView. XML/JSON ( - ) HTTP.
public List<Transaction> transactions(String userId) {
String (). List, Spring JSON XML. , , Java Transaction (- - ):
[
{
"occurred": "28.04.2020 03:18",
"description": "McDonalds - Binging",
"id": 1,
"amount": 10
},
{
"occurred": "28.04.2020 06:18",
"description": "Burger King - Never enough",
"id": 2,
"amount": 15
}
]
Spring MVC , JSON? XML? YAML? REST , ?
Spring .
, , , REST .
? Accept HTTP-.
GET http://localhost:8080/transactions/{userid}
Accept: application/json
Spring MVC Accept : JSON (application/json), List JSON. ( . , Accept .)
, HTTP, .
. .
RESTful API , JSON XML. , REST :
POST http://localhost:8080/users
{"email": "angela@merkel.de"}
Spring , JSON, XML YAML? , , , Content-Type.
POST ...
Content-Type: application/json; charset=UTF-8
...
REST ?
package com.marcobehler.springmvcarticle;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BookingController {
@PostMapping("/transactions")
public Transaction transaction(@RequestBody TransactionDto dto) {
Transaction transaction = null;
return transaction;
}
}
.
public Transaction transaction(@RequestBody TransactionDto dto) {
@RequestParam @Pathvariable, , @RequestBody.
@RequestBody Content-Type Spring , HTTP- Content-Type, : JSON .
Transaction transaction = null;
return transaction;
}
JSON, TransactionDTO, , Transaction, . Spring MVC.
: Spring Accept Content-Type, , Java JSON. XML. .
( / / .)
, Spring MVC , HttpMessageConverters.
HttpMessageConverter?
HttpMessageConverter — ( , , ).
- canRead (MediaType) → (JSON | XML | YAML | . .)? MediaType Content-Type.
- canWrite (MediaType) → (JSON | XML | YAML | . .)? MediaType, , Accept.
- read(Object, InputStream, MediaType) → Java- (JSON | XML | YAML | . .) InputStream
- write(Object, OutputStream, MediaType) → Java- OutputStream (JSON | XML | YAML | . .)
, MessageConverter , MediaTypes (, application/json), / .
HttpMessageConverters?
, . Spring MVC , HTTPMessageConverters — .
, . , Spring AllEncompassingFormHttpMessageConverter ( ).
static {
ClassLoader classLoader = AllEncompassingFormHttpMessageConverter.class.getClassLoader();
jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
}
.
jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
Spring MVC javax.xml.bind.Binder , , , JAXB.
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
Spring MVC ..jackson..ObjectMapper ..jackson..JsonGenerator , , , Jackson JSON.
jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
Spring MVC ..jackson..XmlMapper , , , XML Jackson s XML.
. Spring HttpMessageConverter , «».
if (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
if (jackson2Present) {
addPartConverter(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
addPartConverter(new GsonHttpMessageConverter());
}
: Spring Boot
Spring Boot Spring MVC . Spring Boot Jackson .
JSON Spring Boot, HttpMessageConverts .
: REST
HTML JSON / XML , Model View.
Java, Spring MVC JSON / XML , HttpMessageConverters.
, :
- .
- Accept Content-Type .
- ?
GitHub:
https://github.com/marcobehler/spring-mvc-article
SpringMvcArticleApplication, -.
Spring MVC Spring Boot?
: , Spring Boot Spring MVC.
Spring Framework?.
Spring MVC?
Spring MVC, Spring Boot .
- : https://start.spring.io/.
- Spring Web .
/ RESTful- Spring MVC.
HTTP- Spring MVC?
Spring MVC , HTTP — .
, JSON, XML HTTP (Multipart) Fileuploads, Spring Java.
HTTP- Spring MVC?
Spring MVC HttpServletResponse — .
HTML, JSON, XML WebSocket. , Java .
REST
- HTML , @ResponseBody , XML / JSON.
- REST , @ResponseBody. @ResponseBody .
@Controller
@ResponseBody
public @interface RestController {
- REST XML / JSON HTML.
. XML JSON — , Spring MVC. / REST - , , YAML. , HttpMessageConverter ApplicationContext.
?
, , Thymeleaf Spring, . , Thymeleaf ( ), , .
404? .
, , JSON XML, @ResponseBody.
Spring 404 Not Found .
package com.marcobehler.springmvcarticle;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class _404WithMissingResponseBodyController {
@GetMapping("/users/{id}")
public User getUser_404(@PathVariable String id) {
return new User("Everyone's name is John", id);
}
@GetMapping("/users2/{id}")
@ResponseBody
public User getUser_200(@PathVariable String id) {
return new User("Everyone's name is John", id);
}
}
: @ResponseBody REST .
, ?
HTTP , .
@PostMapping("/users")
public void method1() {
}
@GetMapping("/users")
publi void method(2) {
}
HTTP , .
@PostMapping("/users")
public void method1() {
}
@PostMapping("/users")
publi void method(2) {
}
IllegalStateException, .
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'howToPassAndRetrieveRequestParametersController' method
com.marcobehler.springmvcarticle.HowToPassAndRetrieveRequestParametersController
to {POST /users3}: There is already 'howToPassAndRetrieveRequestParametersController' bean method
URL @RequestParams?
, Spring URL. :
, , , «+» , , marco+wantsnospam@marcobehler.com.
@GetMapping("/confirm")
public void confirm(@RequestParam String email, @RequestParam String token){
}
‘+’ URL - , @RequestParam?
«marco[space]wantnospam@marcobehler.com», Spring + , RFC3986.
: , URL-, , : marco%2Bwantsnospam@marcobehler.com, Spring .
HttpSession ?
Spring MVC REST HttpSession , Spring ( , ).
@RestController
public class HttpSessionController {
@GetMapping("/session")
public String getSession(HttpSession httpSession) {
System.out.println("httpSession = " + httpSession);
return httpSession.getId();
}
}
, HttpSession .
@Service
class SomeOtherService {
@Autowired
private HttpSession httpSession;
public HttpSession getHttpSession() {
return httpSession;
}
}
HttpServletRequest?
Spring MVC REST HttpServletRequest , Spring (, )
@RestController
public class HttpServletRequestController {
@Autowired
private SomeRequestService someRequestService;
@GetMapping("/request")
public String getRequest(HttpServletRequest request) {
System.out.println("request = " + request);
return request.toString();
}
}
, HttpServletRequest .
@Service
class SomeRequestService {
@Autowired
private HttpServletRequest httpServletRequest;
public HttpServletRequest getRequest() {
return httpServletRequest;
}
}
HTTP ?
, , . @RequestHeader.
, .
package com.marcobehler.springmvcarticle;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.Map;
@Controller
public class HttpHeaderController {
@GetMapping("/headers1")
public void singleHeader(@RequestHeader("x-forwarded-for") String xForwardedFor) {
}
@GetMapping("/headers2")
public void headersAsMap(@RequestHeader Map<String,String> headers) {
}
@GetMapping("/headers3")
public void headersAsObject(HttpHeaders headers) {
}
}
cookie?
cookie @CookieValue . cookie HttpServletResponse.
package com.marcobehler.springmvcarticle;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
@Controller
public class CookieController {
@GetMapping("/cookie")
public void handle(@CookieValue("JSESSIONID") String cookie, HttpServletResponse response) {
response.addCookie(new Cookie("SOME_COOKIE_NAME", "This is a crazy new cookie!"));
}
}
IP- ?
. httpServletRequest.getRemoteAddr(), , , IP- -, , 99,99% Nginx Apache.
, X-Forwarded-For IP-. , , , CDN, CloudFront? X-Forwarded-For :
X-Forwarded-For: MaybeSomeSpoofedIp, realIp, cloudFrontIp
, , , , X-Forwarded-For. IP-. CloudFront , IP- CloudFront . !
, IP. , !
package com.marcobehler.springmvcarticle;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
public class IpController {
private static final String[] HEADERS_TO_TRY = {
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_X_FORWARDED_FOR",
"HTTP_X_FORWARDED",
"HTTP_X_CLUSTER_CLIENT_IP",
"HTTP_CLIENT_IP",
"HTTP_FORWARDED_FOR",
"HTTP_FORWARDED",
"HTTP_VIA",
"REMOTE_ADDR"};
@GetMapping("/ip")
public String getClientIpAddress(HttpServletRequest request) {
for (String header : HEADERS_TO_TRY) {
String ip = request.getHeader(header);
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
return getRealClientIpAddress(ip);
}
}
return request.getRemoteAddr();
}
public String getRealClientIpAddress(String ipString) {
String[] manyPossibleIps = ipString.split(",");
for (int i = manyPossibleIps.length - 1; i >= 0; i--) {
String rightMostIp = manyPossibleIps[i].trim();
if (isKnownAddress(rightMostIp)) {
continue;
} else {
return rightMostIp;
}
}
return ipString;
}
private boolean isKnownAddress(String rightMostIp) {
return false;
}
}
Spring MVC?
, HTML-, :
<form method="POST" enctype="multipart/form-data" action="/upload">
File to upload:<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
@PostMapping MultiPartFile, .
package com.marcobehler.springmvcarticle;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@Controller
public class FileUploadController {
@PostMapping("/upload")
public String handleFileUpload(@RequestParam MultipartFile file) throws IOException {
final Path uploadDestination = Paths.get("C:\\uploads").resolve(file.getName());
file.transferTo(uploadDestination);
return "redirect:/";
}
}
(xls, pdf, csv, jpg, zip) Spring ?
, HttpServletResponse byte[] .
, Spring- 'ResponseEntity '. , , .
- → FileSystemResource
- → ClassPathResource
- «-» → InputStreamResource
- byte[] → ByteArrayResource
, , HTTP- ( , ..).
package com.marcobehler.springmvcarticle;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.server.ResponseStatusException;
import java.io.IOException;
@Controller
public class FileDownloadController {
@RequestMapping(value = "/download/{jpgName}", method = RequestMethod.GET)
public ResponseEntity<Resource> downloadJpg(
@PathVariable String jpgName) throws IOException {
final ClassPathResource downloadResource = new ClassPathResource(jpgName);
if (!downloadResource.exists()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
headers.setContentLength(downloadResource.contentLength());
headers.setContentDispositionFormData("attachment", jpgName);
return new ResponseEntity<>(downloadResource, headers, HttpStatus.OK);
}
}
?
Spring MVC , , .
ControllerAdvice RestControllerAdvice @ResponseStatus @ExceptionHandler. :
- , REST .
- @ResponseStatus HTTP, .
- @ExceptionHandler , -.
- , REST .
package com.marcobehler.springmvcarticle;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(SomeConflictException.class)
public String handleConflict(SomeConflictException e, Model model) {
model.addAttribute("message", e.getMessage());
return "new-template";
}
@ResponseStatus(HttpStatus.NOT_IMPLEMENTED)
@ExceptionHandler(NotYetImplementedExceptoin.class)
public void handleBandwithLimitExceeded(NotYetImplementedExceptoin e) {
}
}
(400, 404 ..) ?
ResponseStatusException , , .
ResponseEntity, .
package com.marcobehler.springmvcarticle;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.server.ResponseStatusException;
@Controller
public class HttpStatusCodeController {
@GetMapping("/somePath")
public void alwaysThrowsException() {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Well, that just wasn't right!");
}
}
XYZ Spring MVC?
Spring MVC , , -.
, , , ViewHandlers, InitBinders, RootContexts, , .., Spring MVC. , .
. , :
- Spring MVC — MVC-, - HTML JSON/XML -.
- , Spring, Spring Boot.
- -, , HTTP- / .
Isso é tudo por hoje. Obrigado pela leitura.
Agradecimentos
Muito obrigado a Patricio "Pato" Moschcovich , que não apenas corrigiu este artigo, mas também deu um feedback inestimável!