目录:
第一部分:
一、请求method
springboot的请求注解是@RequestMapping(value = "/user/home",method= RequestMethod.GET)
spring4.3以后可以使用: @GetMapping("/user/home2")
,@PostMapping("/user/create")
等语义化表示get,post等请求方法。
二、传递参数的3种方式
1.RequestParam
@RequestParam 默认必填,可以设置非必填,和默认值
:
/**
* @RequestParam 注解默认是参数必须提供值
* @param username
* @param password
* @return
*/
@PostMapping("/user/create")
@ResponseBody
public String create(@RequestParam(value = "username",defaultValue = "admin") String username, @RequestParam(value="password",required = false) String password){
return "user create, username=" + username + ",password="+password;
}
2.url方式 @PathVariable
/**
* 获取url的方式/user/1 ,/user/2
* @param id
* @return
*/
@GetMapping("/user/{id}")
@ResponseBody
public String display(@PathVariable("id") String id){
return "user display is=" + id;
}
3.HttpServletRequest方式
@ResponseBody
@GetMapping("/user/ip")
public String edit(HttpServletRequest req){
return "user edit " + req.getRemoteHost();
}
三、@RestController
这个注解相当于@Controller+@RequestBody,用在视图访问层,表示当前controller的方法的返回值并可以直接用于body测试.返回json格式数据:
四、springboot的数据渲染到jsp页面
需要的步骤:
1.配置文件:
application.properties加入2个配置项,执行页面路径和后缀
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
2.加入 tomcat-embed-jasper的依赖
pom.xml中:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!-- <version>9.0.27</version>-->
</dependency>
<!--servlet依赖jar-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!--Jstl标签依赖的jar包start-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
build下加入resoures
<resources>
<!-- <resource>-->
<!-- <directory>src/main/java</directory>-->
<!-- <includes>-->
<!-- <include>**/*.xml</include>-->
<!-- </includes>-->
<!-- </resource>-->
<!-- <resource>-->
<!-- <directory>src/main/resources</directory>-->
<!-- <includes>-->
<!-- <include>**/*.*</include>-->
<!-- </includes>-->
<!-- </resource>-->
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
3.测试:
@Controller
public class LoginController {
@PostMapping("/login")
public String login(@RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {
if (username.equals(password)) {
return "ok";
}
return "fail";
}
/**
* 给jsp传参数,类似req.setAttribute
* @param model
* @return
*/
@GetMapping("/login")
public String loginIndex(Model model){
model.addAttribute("username", "root");
return "login";
}
}
login.jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>this is login page</h1>
<p>username is ${username}</p>
</body>
</html>
运行入口函数
@SpringBootApplication
public class Demo11Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo11Application.class, args);
}
}
五、springboot渲染数据到freemarker页面:
在springboot中使用freemarker的步骤
1. 在pom.xml里面加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.配置文件修改freemarker的位置和后缀
看配置信息可以看源码: FreeMarkerProperties
:我们在application.properties中修改配置信息:
spring.freemarker.templateLoaderPath=classpath:/ftl/
spring.freemarker.suffix=.ftl
3.测试:
@Controller
public class AccountController {
@RequestMapping("/reg")
public String req(Model model){
model.addAttribute("username", "root");
return "reg";
}
}
@SpringBootApplication
public class Demo11Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo11Application.class, args);
}
}
六、更换web容器
pringboot 容器默认使用的是tomcat作为外部容器, 可以更换为jetty。具体操作如下:
1.排除tomcat,加入jetty的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 排除tomcat-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
2.测试:
运行入口函数:
@SpringBootApplication
public class Demo11Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Demo11Application.class, args);
}
}
源码地址:https://github.com/hufanglei/springboot-v-study/tree/springboot-web1
第二部分
一、请求静态资源:
1. 放在webapp下 加resources.xml 可以访问到
做个案例,测试下:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/webapp</directory>
<!--注意此次必须要放在此目录下才能被访问到 -->
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
-
入口函数启动:
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
2. springboot默认的静态资源的路径是:
-
“classpath:/META-INF/resources/”, -
“classpath:/resources/”, -
“classpath:/static/”, -
“classpath:/public/” };
我们可以在ResourceProperties源码中找到这个原因:在public下准备个文件看下能否访问到:
运行入口函数:看下页面,显示已经访问到public下的html页面和css。
3.可以通过spring.resources.static-locations 配置项修改默认静态资源路径
试一试:我们指定html文件下为我们的默认静态资源路径,并准备个login.html,看下能否访问:运行,看下页面效果:
结果显示已经访问到html下的页面。修改默认的静态资源路径成功。
二、sevlet,filter,listener的2种配置方式:
1.springboot如何使用servlet
有2种方式,一种是用sevlet3加入口函数注解扫码方式,一种是配置类注入servlet方式: 现在动手试试:
① 方法一:(servlet3可以使用这种方法)
-
1)编写servlet,然后加上响应的注解@WebServlet -
2)需要启用@ServletComonentScan注解
@WebServlet("/user.do")
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public BookServlet() {
System.out.println("===servet BookServlet========");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("book servlet");
}
}
@ServletComponentScan
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
运行入口,访问BookServlet 映射的user.do路径:说明servlet已经访问成功。
② 方法2:(servlet2.5及以下版本可以使用这种方法)
-
1) 书写servlet无需对位映射,不用加@WebServlet注解 -
2)书写个配置类,使用@Bean注入,注入的话,需要调用ServletRegistrationBean的构造方法。代码如下: servlet:
public class BookServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public BookServlet() {
System.out.println("===servet BookServlet========");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("book servlet");
}
}
配置类:
@SpringBootConfiguration
public class ServletConfigration {
@Bean
public ServletRegistrationBean createBookServlet(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new BookServlet(), "/book.do");
return servletRegistrationBean;
}
}
入口函数
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
2.springboot如何使用过滤器
使用的方式和servet差不多,一种是@WebFilter(“/*”)注解方式,另一种是也是通过配置类: 不过生成filter的类是 fileter -》 FilterRegistrationBean。
方式1通过@WebFilter(“/*”)+入口@ServletComponentScan注解实现过滤器
@WebFilter("/*")
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("==LogFilter =init===");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("==LogFilter =filter ==="+ request.getRemoteHost());
chain.doFilter(request,response);
}
@Override
public void destroy() {
System.out.println("=====destroy======");
}
}
入口函数
@ServletComponentScan
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
启动入口函数,访问刚才的servlet,看下控制台打印情况:显示过滤器已经被注入了。
方式2:配置类+注入bean,
代码:
public class EchoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
System.out.println("spring boot web filter "+ req.getRequestURI());
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
配置类:
@SpringBootConfiguration
public class ServletConfigration {
@Bean
public FilterRegistrationBean createFilterRegistrationBean(){
FilterRegistrationBean filter = new FilterRegistrationBean();
filter.setFilter(new EchoFilter());
filter.setUrlPatterns(Arrays.asList("/book.do"));
return filter;
}
}
入口函数
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
3.springboot如何使用监听器
1)方式1:@WebListener+@ServletComponentScan
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("StartUpListener app startup at " + LocalDateTime.now().toString());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
@ServletComponentScan
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
2)方式2:配置类+@bean+ServletListenerRegistrationBean构造函数注入
public class StartUpListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("StartUpListener app startup at " + LocalDateTime.now().toString());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
@SpringBootConfiguration
public class ServletConfigration {
@Bean
public ServletListenerRegistrationBean createServletListenerRegistrationBean(){
ServletListenerRegistrationBean listener = new ServletListenerRegistrationBean(new StartUpListener());
return listener;
}
}
@SpringBootApplication
public class Demo12Application {
public static void main(String[] args) {
SpringApplication.run(Demo12Application.class, args);
}
}
启动:源码地址:https://github.com/hufanglei/springboot-v-study/tree/demo12
第三部分
1.拦截器:
拦截器的使用步骤
①写一个拦截器,实现HandlerInterceptor接口
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LogHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=========preHandle===============" + handler);
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("=========postHandle===============" + handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("=========afterCompletion===============" + handler);
}
}
preHandle:controller执行之前调用 postHandle:controller执行之后,且页面渲染之前调用 afterCompletion:页面渲染之后调用,一般用于资源清理操作
②写一个类,实现WebMvcConfigurer接口,重写addInterceptors方法(已经过时),并调用registry.addInterceptor把上一步的拦截器加进去
@SpringBootConfiguration
public class WebConfiguration implements WebMvcConfigurer {
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/web/**").addResourceLocations("classpath:/web/");
// }
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogHandlerInterceptor());
}
}
测试
写个controller
@RestController
public class UserController {
@GetMapping("/user/home")
public String home(){
return "user home";
}
@GetMapping("/user/help")
public String help() {
throw new IllegalArgumentException("args is empty");
}
}
@SpringBootApplication
public class Demo13Application {
public static void main(String[] args) {
SpringApplication.run(Demo13Application.class, args);
}
}
2.异常处理:
1)默认异常处理逻辑ErrorMvcAutoConfiguration
当我们访问一个不存在的url时候会出现如下页面:看下ErrorMvcAutoConfiguration源码:
排除springboot默认显示的异常页方式1:
可以看到找到就是渲染的这段代码。我们可以关闭这个默认异常页配置:看了源码再去修改applicaiton.properties
server.error.whitelabel.enabled=false
排除springboot默认显示的异常页方式2:
也可以直接在入口函数上,用exclude去排除自动注册的这个默认异常注册类:
@SpringBootApplication(exclude = ErrorMvcAutoConfiguration.class)
public class Demo13Application {
public static void main(String[] args) {
SpringApplication.run(Demo13Application.class, args);
}
}
2).自处理异常
定义一个controller。手动抛出异常:
①在当前controller类使用@ExceptionHandler处理异常
@RestController
public class BookController {
// @ExceptionHandler(value = FileNotFoundException.class)
@ExceptionHandler(value = FileNotFoundException.class)
public String error(Exception e){
return "file not found exception==== " + e.getMessage();
}
@GetMapping("/book/error1")
public String list() throws FileNotFoundException {
throw new FileNotFoundException("file not found");
}
@GetMapping("/book/error2")
public String error2() throws ClassNotFoundException {
throw new ClassNotFoundException("file not found");
}
@GetMapping("/user/null")
public String empty() {
throw new NullPointerException("args is empty");
}
}
我们看到访问list,error2,empty的方法都会抛出异常,同时定义一个处理异常的方法error:
@ExceptionHandler(value = FileNotFoundException.class)
public String error(Exception e){
return "file not found exception==== " + e.getMessage();
}
如果匹配到 @ExceptionHandler中value对应的异常,就可以在error方法中处理异常,或者跳转到错误页面。我们访问/user/null:因为
@GetMapping("/user/null") public String empty() { throw new NullPointerException("args is empty"); } }
对应的是空指针异常,而 @ExceptionHandler(value = FileNotFoundException.class)
是文件找不到的异常,所以controller没给我们处理。
然后访问@GetMapping(“/book/error1”)看到已经帮我们处理了。如果想要@ExceptionHandler当前类全部的方法,就可以扩大异常范围,改成exception.class就可了。
@ExceptionHandler(value = Exception.class)
public String error(Exception e){
return " exception==== " + e.getMessage();
}
②全局处理异常的2种方式:
-
a.方式1:使用ErrorPageRegistrar的接口
写一个类,实现ErrorPageRegistrar接口,实现registerErrorPages,在该方法里面,添加具体的错误处理逻辑
@Component
public class CommonErrorRegistry implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
ErrorPage e500 = new ErrorPage(INTERNAL_SERVER_ERROR, "/500.html");
ErrorPage argsPage= new ErrorPage(IllegalArgumentException.class, "/args.html");
registry.addErrorPages(e404, e500,argsPage);
}
}
-
b.方式2:@ControllerAdvice 具体做法:
-1.写一个类,需要加上@ControllerAdvice注解 -2.写一个异常处理方法,需要加上@Exception(value=Exception.class)这个注解,在该方法上处理异常,
@ControllerAdvice
public class GloabalExceptinHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
public String errorHandler(Exception e){
return "gloabal error " + e.getClass().getName()+ " =="+ e.getMessage();
}
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public String errorHandler2(Exception e){
return "gloabal error2 " + e.getClass().getName()+ " =="+ e.getMessage();
}
}
这2种方法都可以跳转到自定义的页面,或者抛出异常。看下这个ErrorPage类的源码:可以看到,errorpage可以通过请求响应状态码控制跳转页面,可以根据具体异常控制跳转页。
演示代码git地址:https://github.com/hufanglei/springboot-v-study/tree/springbootweb3
以上就说了springbootweb的大体内容,基础springboot2的。关于请求方法参数,数据渲染到jsp页面和freemarker页面的配置方式,替换内置tomcat的方法,请求静态页面的设置,过滤器,监听器,servlet的2种注册方式,拦截器的自定义,异常处理的类上的处理,和全局处理的2种方式。
个人微信公号:怒放de每一天 。不定时推送相关文章,期待和大家一起成长!!
完
原文始发于微信公众号(怒放de每一天):springboot原理实战(14)–springbootweb
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/106623.html