spring mvc jsp页面传对象给controller 为空_Java的学习(38)spring的进阶

ResponseBody和RequestBody

@ResponseBody把后台pojo转换json对象,返回到页面。
@RequestBody接受前台json数据,把json数据自动封装javaBean

请求和响应都是json数据

导入jar包

73106fded2a937972411512d8bccc624.png

在DispatcherServlet-servlet.xml中添加个json转换器

e31500503d73fd06f79149966894a0d7.png

写个jsp页面,提交json请求参数

b40f20dae5469a8017656110eae696b6.png

f6ea98d7ae8c2ac5cfaef02b1bb69782.png

后台处理

309c7258e6c444d70f17f9a0d52cd859.png

a74d25d862468262f572f7a578563fbf.png

Springmvc多视图

多视图是一个方法可以返回json/xml等格式的数据

导入xml格式支持的jar包

ac6834a8143bf174a13d696e99873ae8.png

配置支持多视图

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
		<!-- 配置支持媒体类型 -->
		<property name="contentNegotiationManager">
			<bean class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
				<property name="mediaTypes">
					<map>
						<entry key="json" value="application/json"></entry>
						<entry key="xml" value="application/xml"></entry>
					</map>
				</property>
			</bean>
		</property>

		<!-- 指定默认视图 -->
		<property name="defaultViews">
			<!-- 支持多个视图 -->
			<list>
				<!-- 对josn格式视图支持 -->
				<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

				<!-- xml格式视图支持 -->
				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
					<constructor-arg>
						<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
							<property name="classesToBeBound">
								<list>
									<value>com.gyf.backoffice.domain.Student</value>
								</list>
							</property>
						</bean>
					</constructor-arg>
				</bean>
			</list>
		</property>
	</bean>

控制器提供一个接口

e88543f1487834a15420f2178eedaf80.png

测试

39ac4128f989db364885bd1d11a89182.png

Spring + SpringMVC + Mybatis整合

导入jar包

04e304d69e5f2239c66e9615378b8ea9.png

在项目目录下创建config目录,在其中创建springMVC.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" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.2.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

    <!-- 1.配置注解扫描位置 -->
    <context:component-scan base-package="com.gyf.backoffice.web.controller" />


    <!-- 2.配置注解处理映射-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>

    <!--3.配置适配器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">

    </bean>

    <!-- 4.配置springmvc视图解析器 视图解析器解析的视频路径为:前缀 + 后缀 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

在web.xml添加springmvc配置

		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 3.0的springmvc 默认加载WEB-INF下的dispatcher-servlet.xml文件 3.2的springmvc 
			加载DispatcherServlet-servlet.xml文件 -->
		<init-param>
			<!-- 修改黑底springmvc加载的配置文件路径 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

先配置一个Controller跑出一个页面

b9663681fb4274e93dc5b86aed3c07a2.png

导入逆向工程生成JavaBean/Mapper

6def44bba08280c93fed38c7b27ffac8.png

修改ItemsMapper.java和ItemsMapper.xml增加一个查询所有数据的功能

c1910dde84f8419e54bb150fa9648e21.png

定义Service层接口并实现

e0b9a681913a6f49ca9ab23198d03c64.png

配置mybatis.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 别名配置 -->
	<typeAliases>
		<!-- 批量配置别名:指定批量定义别名的类包,别名为类名(首字母大小写都可) -->
		<package name="com.gyf.backoffice.domain"/>
	</typeAliases>
	<mappers>
		<!-- 批量加载映射文件 -->
		<package name="com.gyf.backoffice.mapper"/>
	</mappers>
</configuration>

创建spring的applicaiontContext.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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context-3.2.xsd 
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 
		http://www.springframework.org/schema/tx 
		http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
	<!-- 1.加载db配置文件  -->
	<context:property-placeholder location="classpath:db.properties"/>

	<!-- 2.配置c3p0数据源 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}"/>
		<property name="jdbcUrl" value="${jdbc.url}"/>
		<property name="user" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
		<property name="maxPoolSize" value="30"/>
		<property name="minPoolSize" value="2"/>
	</bean>

	<!-- 3.让spring管理sqlsessionFactory -->
	<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource"/>
		<!-- 指定配置文件位置 -->
		<property name="configLocation" value="classpath:mybatis.xml"/>
	</bean>
	
	<!-- 4.配置mapper扫描器.批量扫描创建代理对象 -->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.gyf.backoffice.mapper"/>
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
	</bean>
</beans>

db.properties数据库配置信息

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

Web.xml配置spring容器

<!-- spring的配置 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

applicationContext.xml添加bean的注解装配

<!-- 配置扫描注解 -->
	<context:component-scan base-package="com.gyf.backoffice"/>

ItemsService

72474ff9ada314663e069721f564c3cc.png

ItemsController

1594f2985d9a3ae61a063befb92c9c26.png

这里可以方法items/list.do,是否可以获取数据

applicationContext.xml事务配置

<!-- 5.配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!-- 6.开启事务注解-->
<tx:annotation-driven></tx:annotation-driven>

添加一个保存方法测试事务

60af96ba28fa200b2e238f7f5d7b67af.png

显示商品数据

Controller.java

25b27e132ba807301aabde37aaea3d39.png

Views/items/list.jsp

0c5c45a065c29ff7bc9bf6affa8c0f0f.png

效果:

79424e31e57a540a7e2c78076c57e585.png

删除商品

service

096141cd6947696493fb0d7f3c40408f.png

controller

acca77d69cd79204eba314edac8e2ffa.png

显示编辑商品页面

controller

9d57dde3c6c6255111811650c0fead7e.png

Edit.jsp

9e9c78e9edf44f736452e3e1a9701684.png

效果

7ee96d26e7570e1893b759f477b213c5.png

更新商品

需要在页面中隐藏一个input标签存id

057fef2b6172d2493d5ee8f7f4a34aaf.png

解决乱码,在web.xml配置

<!-- 配置编码过滤器  -->
  	<filter>
  		<filter-name>EncodingFilter</filter-name>
  		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  		<init-param>
  			<param-name>encoding</param-name>
  			<param-value>UTF-8</param-value>
  		</init-param>
  	</filter>
	
	<filter-mapping>
		<filter-name>EncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

controller

d7a3f9580798581b123de292d878bb0b.png

Service:需要改下逻辑

9740b7846cdf6adc48aa99fd11622482.png

文件上传

ad855cec1991be3a35b3dd0239b22cd1.png

导包

8a711572c170dba51fe4aa197ac8bfe2.png

d20f00d501a87a43b4fca8933f9a81f1.png

Springmvc.xml配置支持文件上传

373f74983153e81599869f8b4ff5d01a.png

Html/JS

d47a2e3821148011f389e4ba81a9131b.png

8b31e9fbc862364e7b5b49adfff26e7f.png

后台

@Controller
@RequestMapping("upload")
public class UploadController {
	@RequestMapping("itemsPic")
	public void itemsPic(HttpServletRequest request,String fileName, PrintWriter writer) throws Exception{
		MultipartHttpServletRequest mulRequest = (MultipartHttpServletRequest) request;
		//通过字段名获取文件数据
		MultipartFile  file1 = mulRequest.getFile(fileName);
		
		System.out.println(fileName + ":上传文件大小 " + file1.getSize());
		
		//格式化文件名
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		String saveName = sdf.format(new Date());
		Random rd = new Random();
		for(int i=0;i<3;i++){
			saveName += rd.nextInt(10);//添加三个随机数
		}
		
		//文件后缀名
		String suffix = file1.getOriginalFilename().split(".")[1];
		
		String saveFileName = saveName + "." + suffix;
		
		//文件保存目录
		String dir = request.getServletContext().getRealPath("/upload");
		File dirFile = new File(dir);
		if(dirFile.exists() == false)dirFile.mkdirs();
		
		//文件保存路径
		String relativePath = "/upload/" + saveFileName;
		String totalPath = request.getServletContext().getRealPath(relativePath);
		System.out.println(totalPath);
		
		File newFile = new File(totalPath);
		
		//保存
		FileCopyUtils.copy(file1.getInputStream(), new FileOutputStream(newFile));
		Thread.sleep(2000);
		//file1.transferTo(newFile);
		
		//返回一个相对路径 相对路径和全路径
		String serverIp = "http://127.0.0.1:8080" + request.getServletContext().getContextPath();
		String respJson = "{"imgUrl":"" + serverIp + relativePath+""}";
		
		writer.write(respJson);
	}
}

Oscache页面缓存

导包

ce21b369a5edf193dbf67082ced5a856.png

测试

c9df43c5aeddfba7ed2a3ec30b370db3.png

缓存的作用域(不同浏览器缓存的时间不同)

如果scope是application,不同浏览器访问同一个路径时,时间是一样的

38e9bb93c084a2bb7888a51ff90b75a0.png

缓存刷新时间

933a0d8e189b7e6237e89dc7b33b9f7f.png

固定存储的Key

c534dd1c0d8e9db47a1d1cdc7277f9a4.png

缓存持久化

创建oscache.properties这个配置文件必须在classpath下面:

37efa29883afc85bd1ed3d28a7534854.png
cache.memory=false
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=C:test

访问路径后会在test的application中创建缓存文件

1a20065d0e7d568a8e081d3bc5f5025d.png

Oscache整合ssm项目


商品页面访问量特别大,给商品页面缓存。Items路径下所有请求都缓存。

在web.xml中配置页面缓存

<!-- 配置页面缓存 -->
	<filter>
		<filter-name>oscache</filter-name>	<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
		<init-param>
			<param-name>time</param-name>
			<param-value>3600</param-value>
		</init-param>
		<init-param>
			<param-name>scope</param-name>
			<param-value>application</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>oscache</filter-name>
		<url-pattern>/items/*</url-pattern>
	</filter-mapping>

第一次访问Items下面的页面,控制器方法会执行,第二次就走缓存页面

Springmvc整合freemarker

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本

导包

0b94d643d3d813de2c3cff8fccc19245.png

b5bd49f8d45f7404a32f0b5e1abb4643.png

Springmvc配置freemark

<!-- 配置freemarker -->
	<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="/WEB-INF/views" />
		<property name="defaultEncoding" value="UTF-8"></property>
	</bean>
	
	<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="contentType" value="text/html;charset=utf-8"/>
		<property name="suffix" value=".ftl" />
	</bean>

写一个hello.ftl模板

4230246b9dcc4d45653875b91c010c36.png

ItemsController

470e71f54933fa75f118e3176f921fac.png

测试结果

aa9b5aa889de234b168360adfd134312.png

list.jsp改成list.ftl

<html>
<head>
    <title>Title</title>
</head>
<body>
商品:<br>
<table border="1">
    <tr>
        <td>名称</td>
        <td>价格</td>
        <td>描述</td>
        <td>日期</td>
        <td>操作</td>
    </tr>
    <#list itemsList as items>
        <tr>
            <td>${items.name}</td>
            <td>${items.price}</td>
            <td>${items.detail}</td>
            <td>${items.createtime?string("yyyy-MM-dd HH:mm:ss zzzz")}</td>
            <td>
                <a href="/items/delete.do?id=${items.id}">删除</a>
                &nbsp;<a href="/items/edit.do?id=${items.id}">编辑</a>
            </td>
        </tr>
    </#list>
</table>
</body>
</html>

SpringMVC的拦截器

Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理

登录拦截器

public class LoginInterceptor implements HandlerInterceptor{
	//controller执行后且视图返回后调用此方法
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("返回视图前  后处理");
	}
	//controller执行后但未返回视图前调用此方法
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("未返回视图前 后处理....");
	}
	// controller执行前调用此方法
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("预处理....");
		//如果是登录页面则放行
		if(request.getRequestURI().indexOf("login.do")>=0){
			return true;
		}
		HttpSession session = request.getSession();
		//如果用户已登录也放行
		if(session.getAttribute("user")!=null){
			return true;
		}
		//用户没有登录挑战到登录页面
		request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
		return false;
	}
}

登录控制器

75f13fc1c3ca3a96d2fbec043335ab7b.png

登录界面

e9be8fdfe7b6613cb5c88f6861169947.png

登录拦截器配置

5a6bfc3a156bc744317bce65662e48a2.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值