框架重点:
1. springMVC实现文件的上传与下载,其实也没什么special,只是数据格式不一样了。前后台交互的数据格式可分为Json、xml以及二进制数据。
1.1 SpringMVC提供了这样的一个机制,允许控制器返回的数据不经过正常的视图处理流程,而是直接将返回的数据写入响应体中(response body)。
1.2 springMVC和mybatis一样都会自动封装数据到对象中。还记得没有这些框架时候的样子吗?
request对象的getParameter方法获得参数后,才能放在对象里。
String username = req.getParameter("username");
String password = req.getParameter("password");
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password);
jdbcTemplate:
String sql = "select * from user where username = ? and password = ?";
User user = template.queryForObject(sql,
new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
2. mybatis实现一对多查询。条件查询的动态SQL。日期处理。
建立的实体类要反应一对多的关系。但是实体类分两种,一种用于封装数据库数据,另一种用于返回给前端,避免暴露属性,阉割版。
3. spring感觉没啥重点,提供容器、AOP(事务管理)。
登录的实现:filter、AOP、专用框架。用户的token是怎么生成的?
filter的例子课程有,项目也是这么用的。此外,还可实现统一编码处理、敏感字符过滤(动态代理的好场景)。
过滤器和servlet一样,都要配置拦截路径。只是过滤器是个接口,规定了必须实现的方法。它的核心是doFilter方法,就像servlet的核心是sevice方法。
AOP是微信点餐
框架就是spring-security
IO流,java web的技术。
springMVC框架所需要的依赖:
文件上传下载:Apache提供Commons FileUpload组件jar包。
json处理:
方式一:使用jackson。
jackson-annotations-2.8.9.jar
jackson-core-2.8.9.jar
jackson-databind-2.8.9.jar
方式二:使用fastjson
fastjson-1.2.35.jar
springmvc的配置文件需要配置:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
<property name="features">
<list>
<value>QuoteFieldNames</value> <!-- 输出key时是否使用双引号,默认为true -->
<value>WriteMapNullValue</value> <!-- 是否输出值为null的字段,默认为false -->
<!--
<value>DisableCircularReferenceDetect</value>
<value>WriteDateUseDateFormat</value>
<value>WriteNullStringAsEmpty</value> 字符类型字段如果为null,输出为"",而非null
<value>WriteNullNumberAsZero</value> 数值字段如果为null,输出为0,而非null
<value>WriteNullBooleanAsFalse</value> Boolean字段如果为null,输出为false,而非null
<value>WriteNullListAsEmpty</value> List字段如果为null,输出为[],而非null
-->
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
文件上传:
文件上传是项目开发中最常见的功能。为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器。
上传的文件其实也是一个表单域。nothing special。
上传的本间可以保存在本地的/WEB-INF/upload文件夹下,还可以放在文件服务器下。
1. 获得真实目录:request.getServletContext()..getRealPath() //服务器在保存文件的时候要用到
获取请求行数据: * GET /day14/demo1?name=zhangsan HTTP/1.1
2. (*)获取虚拟目录:/day14
* String getContextPath()
* jsp页面form表单的action路径的写法:虚拟目录+Servlet的路径。 但是ajax使用的都是相对路径啊,貌似这是因为springMVC自动加上的。
3. 获取Servlet路径: /demo1
* String getServletPath()
4. 获取get方式请求参数:name=zhangsan
* String getQueryString()
5. (*)获取请求URI:/day14/demo1
* String getRequestURI(): /day14/demo1
* StringBuffer getRequestURL() http://localhost/day14/demo1
配置文件
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="200000"/>
</bean>
用于上传的表单页面/WEB-INF/jsp/upload.jsp
<%@ page language="java" pageEncoding="UTF-8"%>
<form method="POST" enctype="multipart/form-data">
yourfile: <input type="file" name="myfiles"/>
yourfile: <input type="file" name="myfiles"/>
yourfile: <input type="file" name="myfiles"/>
<input type="submit" value="上传文件"/>
</form>
核心的UploadController.java
/**
SpringMVC中的文件上传步骤:
@第一步:由于SpringMVC使用的是commons-fileupload实现,故将其组件引入项目中,这里用到的是commons-fileupload-1.2.2.jar和commons-io-2.0.1.jar
@第二步:在####-servlet.xml中配置MultipartResolver处理器。可在此加入对上传文件的属性进行限制
@第三步:在Controller的方法中添加MultipartFile参数。该参数用于接收表单中file组件的内容
@第四步:编写前台表单。注意enctype="multipart/form-data"以及<input type="file" name="**"/> name要和后台接收参数时的名字相同
*/
@Controller
public class TestController {
@RequestMapping(value="/uploadfile",method=RequestMethod.GET)
public String upLoadFile() { return "upload"; }
@RequestMapping(value="/uploadfile",method=RequestMethod.POST)
public String upLoadFile(@RequestParam MultipartFile[] myfiles, HttpServletRequest request) throws IOException {
//如果只是上传一个文件,则只需要MultipartFile类型接收文件即可,而且无需显式指定@RequestParam注解
//如果想上传多个文件,那么这里就要用MultipartFile[]类型来接收文件,并且还要指定@RequestParam注解
//并且上传多个文件时,前台表单中的所有<input type="file"/>的name都应该是myfiles,否则参数里的myfiles无法获取到所有上传的文件
for(MultipartFile myfile : myfiles) {
if(myfile.isEmpty()) {
System.out.println("文件未上传");
continue;
}
else {
System.out.println("文件长度: " + myfile.getSize());
System.out.println("文件类型: " + myfile.getContentType());
System.out.println("文件名称: " + myfile.getName());
System.out.println("文件原名: " + myfile.getOriginalFilename());
System.out.println("===================");
//如果用的是Tomcat服务器,则文件会上传到\%TOMCAT_HOME%\webapps\YourWebProject\WEB-INF\upload\文件夹中
String realPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
//这里不必处理IO流关闭的问题,因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉,我是看它的源码才知道的
FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath + "/" +myfile.getOriginalFilename())); } } return " success_fileupload "; } }
条件查询,动态SQL。
- 根据对象查询
List<User> findByUser(User user);
<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</select>
<sql id="defaultSql">
select * from user
</sql>
使用<where>进行改进
<select id="findByUser" resultType="user" parameterType="user">
<include refid="defaultSql"></include>
<where>
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</where>
</select>
- 根据集合查询
需求:SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)
List<User> findInIds(QueryVo vo); //参数的属性是一个集合,username也可以作为属性放在这个对象里面吗?
<select id="findInIds" resultType="user" parameterType="queryvo">
<include refid="defaultSql"></include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
一对多,多里面就要做标记。
User--Account
-
利用账户查用户
方式一:SQL查询结果可能需要定义一个新的实体类来进行封装。
<select id="findAll" resultType="accountuser">
select a.,u.username,u.address from account a,user u where a.uid =u.id;
</select>
方式二:“多”持有“一”的引用。较方式一更灵活。弊端是需要制定映射关系,因为要制定封装方法。SQL关键字:association*。
<resultMap type="account" id="accountMap">
<id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/><!-- 它是用于指定从表方的引用实体属性的 --> <association property="user" javaType="user"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="birthday" property="birthday"/> <result column="address" property="address"/> </association>
</resultMap>
<!--sql语句-->
<select id="findAll" resultMap="accountMap">
select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
</select> -
利用用户查询账户
用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息
查询出来,我们想到了左外连接查询比较合适。
一持有多的集合。
SQL关键字collection
<resultMap type="user" id="userMap">
<id column="id" property="id"></id>
<result column="username" property="username"/>
<result column="address" property="address"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/><!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型--> <collection property="accounts" ofType="account"> <id column="aid" property="id"/> <result column="uid" property="uid"/> <result column="money" property="money"/> </collection>
</resultMap>
<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
a on u.id =a.uid
</select> -
多对多。比如权限管理里面全是多对多。三表等值连接。
需求:实现查询所有对象并且加载它所分配的用户信息。
多对多也是要被拆分成一对多的。只不过谁持有谁的集合的引用是不确定的。
页面上传文件,关键是文件的保存位置。
图片服务器:这就简单了,调用API即可。后两者都需要找到文件夹的路径。下面两者需要获取物理路径。
项目里面
webapps里面
页面下载文件
向页面返回什么?对于页面识别的类型还需要进行强制下载。
没有request怎么获取项目IP和端口?场景:定时任务、向注册中心注册自己
网友评论