Spring学习笔记-C5-SpringMVC起步
来源:互联网 发布:淘宝买的发票是真的吗 编辑:程序博客网 时间:2024/06/05 18:31
Chapter05 SpringMVC起步
5.1 请求在SpringMVC组件之间的流转
- 请求发送
- DispatcherServlet查询一个或多个HandlerMapping来确定请求的下一站。
- 按照HM查询结果,将请求转发到指定的Controller。
- Controller返回ModelAndView给DispatcherServlet。
- DispatcherServlet使用视图解析器ViewResolver将逻辑试图名匹配为一个特定的视图实现(一般是JSP)。
- 将Model传出给视图实现,渲染试图。
- 将渲染结果通过响应对象(Response)传递给客户端。
5.2 使用Java类来搭建SpringMVC
传统配置SpringMVC是用web.xml+Spring配置文件结合的方式。
但是如果你的容器支持Servlet3.0(Tomcat7及以上)
package chapter05;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;/** * 配置DispatcherServlet * @author NikoBelic * @create 30/12/2016 10:43 */public class SpittrWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ /** * 指定ContextLoaderListener配置类 * @Author NikoBelic * @Date 30/12/2016 10:48 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[]{RootConfig.class}; } /** * 指定SpringMVC配置类 * @Author NikoBelic * @Date 30/12/2016 10:49 */ @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[]{WebConfig.class}; } /** * 将DispatcherServlet映射到 "/" * @Author * @Date 30/12/2016 10:44 */ @Override protected String[] getServletMappings() { return new String[]{"/"}; }}
/** * 最小但可用的SpringMVC配置 * @author NikoBelic * @create 30/12/2016 10:50 */@Configuration@EnableWebMvc@ComponentScan("chapter05")public class WebConfig extends WebMvcConfigurerAdapter{ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } /** * 配置静态资源的处理 * @Author NikoBelic * @Date 30/12/2016 12:15 */ @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); }}
/** * 最小但可用的SpringMVC配置 * @author NikoBelic * @create 30/12/2016 10:50 */@Configuration@EnableWebMvc@ComponentScan("chapter05")public class WebConfig extends WebMvcConfigurerAdapter{ @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setExposeContextBeansAsAttributes(true); return resolver; } /** * 配置静态资源的处理 * @Author NikoBelic * @Date 30/12/2016 12:15 */ @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); }}
Spring上下文的加载方式有两个,一个是使用SpringMVC的DispatcherServlet去加载(控制器、视图解析器、处理器映射器),另一个是用ContextLoaderListener加载(应用中的其他bean,例如Service、Dao)。
如果上程序所写,我们配置WebConfig类来加载SpringMVC需要的bean。配置RootConfig来加载剩余的bean。
5.2 编写基本的控制器
@Controller其实是包含@Component注解的,二者的功能是相同的,但是为了更加清晰的区分不同的组件,使用@Controller来标识这是一个SpringMVC的组件。
@RequestMapping可以加载类上,也可以加载在方法上,有一下几种情况:
1. 类有注解,方法有注解,那么HTTP访问路径为 http://IP:Port/Project/ControllerMapping/MethodMapping
2. 类无注解,方法有注解 http://IP:Port/Project/MethodMapping
3. 类有注解,方法无注解,那么只允许该Controller中只有一个Method,否则启动报错
我们一般使用方法1
@Controller@RequestMapping("home")public class HomeController{ @RequestMapping(value = "list",method = RequestMethod.GET) public String home() { return "home"; }}
创建一个jsp页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Spittr</title></head><body><h1>Welcome to Spittr</h1><a href="<c:url value="/spittles"/>">Spittles</a><a href="<c:url value="/spitter/register"/>">Spittles</a></body></html>
使用Tomcat启动服务后,项目会根据SpittrWebInitializer配置的信息加载相关的配置文件。
以上构建了一个最简单的一个请求结果展示,那么如果我们需要给前台界面返回一些数据,怎么做?
修改控制器
@Controller@RequestMapping("home")public class HomeController{ @RequestMapping(value = "list",method = RequestMethod.GET) public String home() { return "home"; } @RequestMapping(value = "spittles",method = RequestMethod.GET) public ModelAndView getSpittles(ModelAndView mv) { List<Spittle> spittleList = createSpittleList(10); mv.setViewName("spittle"); mv.addObject("spittleList",spittleList); return mv; } /** * 模拟从数据库获取数据 * @Author NikoBelic * @Date 31/12/2016 13:15 */ private List<Spittle> createSpittleList(int count) { List<Spittle> spittles = new ArrayList<>(); for (int i = 0; i < count; i++) { spittles.add(new Spittle(i,"Spittle " + i ,new Date(),null,null)); } return spittles; }}
创建JSP页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page isELIgnored="false" %><%@ page session="false" %><html><head> <title>Spittr</title></head><body><h1>Spittles</h1><table> <thead> <tr> <td>Id</td> <td>Message</td> <td>Time</td> </tr> </thead> <tbody> <c:forEach items="${spittleList}" var="spittle"> <tr> <td>${spittle.id}</td> <td>${spittle.message}</td> <td>${spittle.time}</td> </tr> </c:forEach> </tbody></table></body></html
5.3 接受请求的输入
Controller中的方法接收参数的方式有很多
以分页请求为例。
Controller
@Controller@RequestMapping("home")public class HomeController{ private static List<Spittle> spittleList; private static final int PAGE_SIZE = 5; static { spittleList = createSpittleList(Math.max(10, new Random().nextInt(100))); System.out.println("随机生成数据:" + spittleList.size()); } @RequestMapping(value = "list", method = RequestMethod.GET) public String home() { return "home"; } /** * 获取Spittles * * @Author NikoBelic * @Date 31/12/2016 22:22 */ @RequestMapping(value = "spittles/{page}", method = RequestMethod.GET) public ModelAndView getSpittles(@PathVariable int page, ModelAndView mv) { Map<String, Integer> pageInfo = getPageInfo(page, spittleList.size()); List<Spittle> pageSpittleList = spittleList.subList(pageInfo.get("start"), pageInfo.get("end")); mv.setViewName("spittle"); mv.addObject("spittleList", pageSpittleList); mv.addObject("totalPage", pageInfo.get("totalPage")); mv.addObject("page", page); return mv; } /** * 模拟从数据库获取数据 * * @Author NikoBelic * @Date 31/12/2016 13:15 */ private static List<Spittle> createSpittleList(int count) { List<Spittle> spittles = new ArrayList<>(); for (int i = 0; i < count; i++) { spittles.add(new Spittle(i, "Spittle " + i, new Date(), null, null));c } return spittles; } /** * 分页工具 * * @Author NikoBelic * @Date 31/12/2016 23:39 */ private Map<String, Integer> getPageInfo(int page, int totalRecord) { Map<String, Integer> pageInfo = new HashMap<>(); int start = (page - 1) * PAGE_SIZE; // 当前页起始index int end; int totalPage = (int) Math.ceil(totalRecord / (float) PAGE_SIZE); if (page != totalPage) end = start + PAGE_SIZE; else { if (totalRecord % PAGE_SIZE != 0) end = (totalPage - 1) * PAGE_SIZE + totalRecord % PAGE_SIZE; else end = start + PAGE_SIZE; } pageInfo.put("start", start); pageInfo.put("end", end); pageInfo.put("page", page); pageInfo.put("totalPage", totalPage); System.out.println("起始:" + start + ",结束:" + end + ",当前页:" + page + ",总页数:" + totalPage + ",总数据:" + totalRecord); return pageInfo; }}
JSP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page isELIgnored="false" %><%@ page session="false" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Spittr</title></head><body><h1>Spittles</h1><table> <thead> <tr> <td>Id</td> <td>Message</td> <td>Time</td> </tr> </thead> <tbody> <c:forEach items="${spittleList}" var="spittle"> <tr> <td>${spittle.id}</td> <td>${spittle.message}</td> <td>${spittle.time}</td> </tr> </c:forEach> </tbody></table><span><a href="${pageContext.request.contextPath}/home/spittles/1">首页</a></span><span><a href="${pageContext.request.contextPath}/home/spittles/<c:out value='${page-1}'/>" <c:if test="${page <= 1}"> hidden="hidden" </c:if>>上一页</a></span><span>当前页:${page}</span><span><a href="${pageContext.request.contextPath}/home/spittles/<c:out value='${page+1}'/>" <c:if test="${page >= totalPage}"> hidden="hidden" </c:if>>下一页</a></span><span><a href="${pageContext.request.contextPath}/home/spittles/${totalPage}">尾页</a></span></body></html>
5.4 处理表单
我们模拟一个用户注册情景
用户通过浏览器请求得到一个注册页面,通过注册页面完成注册后自动跳转到个人信息页面。
Controller
@Controller@RequestMapping("spitter")public class SpitterController{ @Autowired private SpitterDao spitterDao; @RequestMapping(value = "register",method = RequestMethod.GET) public String showRegisterForm() { return "register"; } @RequestMapping(value ="register",method = RequestMethod.POST) public String processRegister(Spitter spitter) { spitterDao.save(spitter); return "redirect:/spitter/" + spitter.getUsername(); } @RequestMapping(value ="{username}" ,method = RequestMethod.GET) public String showSpitterProfile(@PathVariable String username,Model model) { Spitter spitter = spitterDao.findSpitterByUsername(username); model.addAttribute("spitter",spitter); return "profile"; }}
注册表单信息
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page isELIgnored="false" %><%@ page session="false" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>RegisterForm</title></head><body><h1>Register</h1><%--这里Form表单没有设置action,因此他会将请求提交到与展现时相同的URL路径上--%><form method="post"> Username:<input type="text" name="username"/><br/> Password:<input type="password" name="password"/><br/> FirstName:<input type="text" name="firstName"/><br/> LastName:<input type="text" name="lastName"/><br/> <input type="submit" value="Register"/></form></body></html>
个人信息
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ page isELIgnored="false" %><%@ page session="false" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Spittr</title></head><body><h1>Your Profile</h1>${spitter.username}<br/>${spitter.firstName} ${spitter.lastName}</body></html>
Model
public class Spitter{ String username; String firstName; String lastName; String password; public Spitter() { } public Spitter(String username, String firstName, String lastName, String password) { this.username = username; this.firstName = firstName; this.lastName = lastName; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
Dao
@Repositorypublic class SpitterDao{ private List<Spitter> spitterList; public SpitterDao() { this.spitterList = new ArrayList<>(); System.out.println(spitterList); } public void save(Spitter spitter) { spitterList.add(spitter); } public Spitter findSpitterByUsername(String username) { for (Spitter spitter : spitterList) { if (spitter.getUsername().equals(username)) return spitter; } return null; }}
校验表单
- Spring学习笔记-C5-SpringMVC起步
- Spring MVC起步笔记
- Spring学习笔记(18)-----------@ASpectJ学习起步
- SpringMVC学习笔记--Spring Tag
- Maven、Spring 学习起步
- Spring-boot学习起步
- spring-boot起步介绍Demo,廖师兄springboot学习笔记
- Spring学习---Spring MVC起步
- Spring笔记[一]---基础起步
- C5.0算法学习
- C5.0算法学习
- C5.0算法学习
- Spring学习笔记-springMVC校验框架
- Spring学习笔记-springMVC入门Demo
- Spring学习笔记-SpringMVC文件上传
- spring学习笔记(5)-springmvc
- Spring学习笔记-1:SpringMVC hello world
- Spring学习笔记-1:SpringMVC hello world
- unfortunately has stop
- IIS web.config url重写伪静态规则错误
- Android4.4.2编译出错
- 136. Single Number
- 在线等......xmpp
- Spring学习笔记-C5-SpringMVC起步
- asp 页面控件修改
- android 动画的问题
- Exoplayer 播放M3U8格式视频失败
- app连接wifi模块,通过wifi模块串口读取数据失败
- 未安装APK ,动态部署,加载资源布局XML的问题
- Android显示文章问题
- 137. Single Number II
- 想往一个apk里面添加功能,想知道能不能实现