学习Spring MVC的一个例子,参考书籍《Servlet、JSP、Spring MVC学习指南》,简单总结一下。

代码下载:https://github.com/PeiranZhang/springmvc-demo

本文参考链接:

https://www.cnblogs.com/yhtboke/p/5780140.html

https://blog.csdn.net/liubin5620/article/details/79922692

项目目录


这里,没有采用maven来管理依赖,实际项目中可以使用maven方便管理项目,项目依赖的jar包如下所示

项目在IDEA中打包、部署到tomcat,可以参考博客:https://www.cnblogs.com/darange/p/10965700.html

web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- contextConfigLocation配置springmvc加载的配置文件适配器、处理映射器等-->
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/springmvc-config.xml</param-value>
</init-param>
<!--值不为0表示,tomcat启动该应用时,加载servlet,而不是等到第一请求到来时再加载servlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 所有访问都由DispatcherServlet进行解析-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

springmvc-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 与spring注解配合使用,扫描指定包及其子包下面的带有Controller、Service注解下的类,生成bean-->
<context:component-scan base-package="app16a.controller"></context:component-scan>
<context:component-scan base-package="app16a.service"></context:component-scan> <!-- 如果在配置前端控制器时拦截了所有的请求,不做特殊处理就会导致部分静态资源无法使用。如果是这种情况就可以使用下面的配置来访问静态资源文件,所以使用resource配置-->
<!-- 没有<annotation-driven/>,<resources/>元素会阻止任意控制器被调用--> <!-- 配置注解的处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<mvc:resources mapping="/*.html" location="/"/> <!-- 配置视图解析器,在Controller中设置视图名的时候会自动加上前缀和后缀 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

Service

@Service注解可以指定名称,当一个接口有多个实现类时,在Controller里面注入时,可以指定实现类

//service加上名称,在一个接口多个实现类时,可以这样区分
@Service("productService")
public class ProductServiceImpl implements ProductService {
private Map<Long, Product> products =
new HashMap<Long, Product>();
private AtomicLong generator = new AtomicLong();
@Override
public Product add(Product product) {
long newId = generator.incrementAndGet();
product.setId(newId);
products.put(newId, product);
System.out.println("Add" + product);
return product;
} @Override
public Product get(long id) {
return products.get(id);
}
}

Controller

Controller中使用@Qualifier指定具体的service

1.通过@RequestMapping,进行url与处理方法的映射,处理方法返回的是视图的名称,不需要写绝对路径和jsp后缀,这是因为web.xml中配置了视图解析器

2.处理方法里面参数可以自己定义,其中Model对象有spring生成,可以在model中添加对象,作为request对象,发送给jsp

3.注意转发与重定向的区别,代码编写方式可以参考代码。重定向返回的视图名字前加上"redirect:"

https://blog.csdn.net/liubin5620/article/details/79922692

1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();

2、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;

3、转发是服务器行为,重定向是客户端行为;

4、转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;

5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

转发是要比重定向快,因为重定向需要经过客户端,而转发没有。有时候,采用重定向会更好,若需要重定向到另外一个外部网站,则无法使用转发。另外,重定向还有一个应用场景:避免在用户重新加载页面时两次调用相同的动作。

例如,当提交产品表单的时候,执行保存的方法将会被调用,并执行相应的动作;这在一个真实的应用程序中,很有可能将表单中的所有产品信息加入到数据库中。但是如果在提交表单后,重新加载页面,执行保存的方法就很有可能再次被调用。同样的产品信息就将可能再次被添加,为了避免这种情况,提交表单后,你可以将用户重定向到一个不同的页面,这样的话,这个网页任意重新加载都没有副作用;

但是,使用重定向不太方便的地方是,使用它无法将值轻松地传递给目标页面。而采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。由于重定向经过客户端,所以Model中的一切都会在重定向时丢失。但幸运的是,在Spring3.1版本以后,我们可以通过Flash属性,解决重定向时传值丢失的问题。

要使用Flash属性,必须在Spring MVC的配置文件中添加一个<annotation-driven/>。然后,还必须再方法上添加一个新的参数类型:org.springframework.web.servlet.mvc.support.RedirectAttributes。

4.路径变量的使用,@PathVariable

5.获取请求参数,在处理方法中增加参数,并使用注解@RequestParam

Controller代码:

@Controller
public class ProductController {
@Autowired
//按照名称,注入指定的接口实现类
@Qualifier("productService")
ProductService productService;
private static final Log logger =
LogFactory.getLog(ProductController.class); @RequestMapping(value = "/product_input")
public String inputProduct() {
logger.info("inputProduct called");
return "ProductForm";
} //参数productForm中的字段与提交表当中的text文本框name一一对应
@RequestMapping(value = "/product_save")
public String saveProduct(ProductForm productForm, Model model, RedirectAttributes redirectAttributes){
logger.info("saveProduct called");
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(Float.parseFloat(
productForm.getPrice()));
} catch (NumberFormatException e) {
} productService.add(product); //转发
//model里面的内容作为request属性传递给jsp_servlet
//model.addAttribute("product", product);
//return "ProductDetails"; //重定向
// 客户端重新发送请求,Model无效
//通过addFlashAttribute,可以在jsp中引用对象
redirectAttributes.addFlashAttribute(product);
return "redirect:/product_details";
} @RequestMapping(value = "/product_details")
public String productDetail(){
logger.info("productDetail called");
return "ProductDetails";
} //路径变量的使用
//http://localhost:8080/app16a/product/1
@RequestMapping(value = "/product/{id}")
public String productGet(@PathVariable Long id,Model model){
Product product = productService.get(id);
model.addAttribute(product);
logger.info("productGet called");
return "ProductDetails";
} //获取请求参数
//http://localhost:8080/app16a/product?id=1
@RequestMapping(value = "/product")
public String productGetWithParams(@RequestParam Long id,Model model){
Product product = productService.get(id);
model.addAttribute(product);
logger.info("productGetWithParams called");
return "ProductDetails";
}
}

视图

PoductForm.jsp:form表单中各个文本输入控件的name作为request请求参数的键,发送给action指定的url

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Add Product Form</title>
</head>
<body>
<!--product_save与product_save.action效果一样-->
<div id="global">
<form action="product_save.action" method="post">
<fieldset>
<legend>Add a product</legend>
<p>
<label for="name">Product Name: </label>
<input type="text" id="name" name="name"
tabindex="1">
</p>
<p>
<label for="description1">Description: </label>
<input type="text" id="description1"
name="description" tabindex="2">
</p>
<p>
<label for="price">Price: </label>
<input type="text" id="price" name="price"
tabindex="3">
</p>
<p id="buttons">
<input id="reset" type="reset" tabindex="4">
<input id="submit" type="submit" tabindex="5"
value="Add Product">
</p>
</fieldset>
</form>
</div>
</body>
</html>

ProductDetails.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Save Product</title>
</head>
<body>
<div id="global">
<h4>The product has been saved.</h4>
<p>
<h5>Details:</h5>
<%--
Controller里面的Model中的product对象其实是作为request属性传递给jsp的,所以这里用requestScope来引用--%>
Product Name: ${requestScope.product.name}<br/>
Description: ${requestScope.product.description}<br/>
Price: $${requestScope.product.price}
</p>
</div>
</body>
</html>

以上只是对Spring MVC的简单使用

Spring MVC例子的更多相关文章

  1. spring mvc构建WEB应用程序入门例子

    在使用spring mvc 构建web应用程序之前,需要了解spring mvc 的请求过程是怎样的,然后记录下如何搭建一个超简单的spring mvc例子. 1) spring mvc的请求经历 请 ...

  2. spring mvc(注解)上传文件的简单例子

    spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype=”multipart/form-data” 这个是上传文件必须的2.applicationConte ...

  3. 【Spring】简单的Spring MVC入门例子

    前言 测试特性需要搭建一个简单的Spring MVC的例子,遂记录之,只是例子,只为入门者之示例. 版本说明 声明POM文件,指定需引入的JAR. <properties> <spr ...

  4. 基于spring mvc的注解DEMO完整例子

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件.本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mv ...

  5. [翻译]Spring MVC RESTFul Web Service CRUD 例子

    Spring MVC RESTFul Web Service CRUD 例子 本文主要翻译自:http://memorynotfound.com/spring-mvc-restful-web-serv ...

  6. spring mvc的例子

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  7. spring mvc 注解@Controller @RequestMapping @Resource的详细例子

    现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过 ...

  8. Spring MVC的Hello World例子

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/mvc-framework/spring-mvc-hello-world-example.html: ...

  9. Spring MVC介绍和第一个例子

    1.Spring mvc概述 spring mvc是spring提供给web应用框架设计,实际上MVC框架是一个设计理念.它不仅存在java世界中而且广泛在于各类语言和开发中,包括web的前端应用.对 ...

随机推荐

  1. ERP应收应付进阶操作与子流程--开源软件诞生29

    赤龙ERP应收应付进阶讲解--第29篇 用日志记录"开源软件"的诞生 [进入地址 点亮星星]----祈盼着一个鼓励 博主开源地址: 码云:https://gitee.com/red ...

  2. 讲一讲Java的字符串常量池,看完你的思路就清晰了

    前言 很多朋友Java的字符串常量池的概念困扰了很长一段时间,最近研究了一下jvm指令码,终于对它有了大概的了解. 在展示案例前,我们需要先搞清楚一个概念,众所周知,jvm的内存模型由程序计数器.虚拟 ...

  3. Mybatis是如何封装Jdbc的?

    JDBC六个步骤 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //1. 加载驱动 C ...

  4. 添加mysqli扩展

    find / -name phpize 进入mysqli目录下 ./configue -prefix=/usr/local/mysqli . make && make install ...

  5. thinkPHP 无法加载控制器:Hello

    出现这种问题的情况下要看看: (1).控制器的名称是否写对,控制器的命名规范(别忘下class) 控制器的命名规则1.必须采用大驼峰的命名规则2.必须以Controller.class.php来结尾I ...

  6. Crossing River 题解(贪心)

    题目链接 题目大意 t组数据(t<=20) 给你n个人(n<=1000)过河,每个人都有权值,一条船,每次船最多运2个人,每次的花费为两个人的较大花费 求所有人都过河需要的最小花费 题目思 ...

  7. Eclipse导入包

    没有包,会报错: 鼠标放上去会有提示: 如果提示消失,可以使用快捷键:Ctrl+1调出提示信息. List的包有两个,集合里的List使用util包.

  8. 如何测试一个APP

    1.是否支持各种手机系统 2.是否会因为分辨率而出错 3.不同机型能否安装 4.老旧机型 能否通用 5.广告时长 6.测试能否登陆注册 7.卸载时是否会发生意外 8.安装时会不会误认为带病毒 9.用户 ...

  9. 使用github actions 完成一些自动化工作

    github actions 是什么? github actions是github的持续集成及自动化工作流服务,使用起来都比较方便.大部分github actions都可以在https://githu ...

  10. 饱含辛酸开发 WPF CustomControl

    引言 不知不觉间WPF开发已有两年光景,或许有很多人会问WPF还需要学习吗?WPF还有前途吗?其实我也很担心这个问题. .Net Core3.x已经支持WPF开发,.Net 5也宣布要支持WPF.是否 ...