springMVC个人笔记

编程入门 行业动态 更新时间:2024-10-06 22:32:37

springMVC个人<a href=https://www.elefans.com/category/jswz/34/1770047.html style=笔记"/>

springMVC个人笔记

springMVC是采用MVC设计模式的一个表现层轻量级web框架,是最主流的MVC框架之一
springMVC中有Model模型 View视图 Controller控制器以及springMVC特有的Front Controller前端控制器

环境搭建

创建maven工程,选择骨架org.apache.maven.archetypes:maven-archetype-webapp
补充目录结构java,resources,test
导入spring-context,spring-web,wpring-webmvc以及jsp,servlet的jar包

在controller包类(类似于web),在这个包下创建一个类

@Controller                                                     将该类放入spring容器中
//@RequestMapping(path="/users")                                可以使以下所有方法的@RequestMapping省略/users(已注释)
public class helloController { @RequestMapping(path="/hello")                              请求路径public String sayHello() {System.out.println("你好springMVC");return "success";                                       跳转到success.jsp}
}

在resources下创建一个springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>                         需要spring-beans,mvc,context的约束
<beans xmlns=""xmlns:mvc=""xmlns:context=""xmlns:xsi=""xsi:schemaLocation="://www.springframework/schema/beans/spring-beans.xsd://www.springframework/schema/mvc/spring-mvc.xsd://www.springframework/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.le"/>                  开启包扫描
<bean id="InternalResourceView" class="org.springframework.web.servlet.view.InternalResourceViewResolver">创建视图解析器<property name="prefix" value="/WEB-INF/pages/"></property>  配置前缀(除了index.jsp所有页面都放在pages目录下)<property name="suffix" value=".jsp"/>                       配置后缀
</bean>
<mvc:annotation-driven/> 
</beans>

配置webapp下的web.xml

<?xml version="1.0" encoding="UTF-8"?>                           web.xml需要的约束(Servlet3.1)
<web-app xmlns=""xmlns:xsi=""xsi:schemaLocation="://xmlns.jcp/xml/ns/javaee/web-app_3_1.xsd"version="3.1">
<display-name>springmvc-quick</display-name>                    命名(描述性文字,无实际作用)
<welcome-file-list><welcome-file>index.jsp</welcome-file>                       配置初始页
</welcome-file-list> 
<servlet><servlet-name>springmvc</servlet-name>                        核心控制器<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param>                                                  配置初始化参数<param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value>       通过这个参数才能让springmvc.xml被加载</init-param><load-on-startup>1</load-on-startup>                         启动项(在服务器启动的时候就开始初始化)
</servlet>
<servlet-mapping><servlet-name>springmvc</servlet-name><url-pattern>/</url-pattern>                                拦截请求(/* 匹配所有资源 /匹配除了jsp以外的所以资源)
</servlet-mapping>
</web-app>

运行流程
先创建核心容器->springmvc.xml被加载->扫描注解->将controller放入spring容器中
                                                                                 ->创建视图解析器
                                                                                 ->打开springmvc注解的支持

当有资源访问的时候,视图解析器通过访问路径调度到对应的方法上(通过@RequestMapping),最后通过return的值跳转到对应的页面上

备注
@RequestMapping这个注解类似于底下代码


public class BaseServlet extends HttpServlet {                               继承HttpServlet,重写service方法protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uri = req.getRequestURI();                                    获取请求路径String methodName = uri.substring(uri.lastIndexOf('/') + 1);         获取方法名(通过截取请求路径获取)try {Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);Object invoke = method.invoke(this, req, resp);                  反射相关操作} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
}

代码解释
Servlet类都是一个功能对应一个Servlet,通过抽取方法将一堆功能继承在一个Servlet,增加代码可读性维护性
将需要调用的Servlet继承BaseServlet就能实现,并写好注解如@WebServlet("/user/*")
注解这个时候无实际意义,只是使用反射调用对应方法的标记而已
访问/user/add->this(谁调用谁就是this)通过字符串截取获取add->通过反射调用user下的add方法

@RequestMapping注解详解

@RequestMapping(value="/hello",method = RequestMethod.POST) 这个方法只有是Post请求才会被调用(超链接是get请求)
@RequestMapping(value="/hello",params = {“username”}) 接受的参数里必须有username
@RequestMapping(value="/hello",params = {“username=nm$”}) 接收的参数的键和值都要相同
@RequestMapping(value="/hello",headers = {“Accept”}) 请求头里必须有Accept这个参数

springMVC的自动赋值

准备HTML页面

<form action="hello7" method="get">                              
账号<input type="text" name="username"><br/>                     为account里的元素赋值
密码<input type="text" name="password"><br/>
ID<input type="text" name="id"><br/>
用户2<input type="text" name="user.username"><br/>               为account里的user这个实体类里的元素赋值
ID2<input type="text" name="user.id"><br/>
<input type="submit" value="登入!">
</form>

必须有成员变量以及对应的set方法
*获取方法为setUsername->Username->username

@RequestMapping(value="/hello")
public String sayHello(String username,String password) {       如果请求接受到username和password,springMVC将自动为方法参数赋值return "success";
}@RequestMapping(value="/hello")
public String sayHello2(Account account) {                       如果是一个javaBean对象,将自动封装数据                return "success";}

为集合赋值
account里再提供List<User  >,Map<String,User>以及对应的set方法

用户2<input type="text" name="list[0].username"><br/>            为List集合赋值
ID2<input type="text" name="list[0].id"><br/>用户3<input type="text" name="map['first'].username"><br/>       为Map集合赋值
ID4<input type="text" name="map['first'].id"><br/>

中文问题

在web.xml中配置中配置过滤器

<filter><filter-name>filter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value>                        编码为UTF-8</init-param>
</filter>
<filter-mapping><filter-name>filter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

选择不拦截的路径

<mvc:resources mapping="/js/" location="/js/**"/>
<mvc:resources mapping="/images/" location="/js/**"/>
<mvc:resources mapping="/css/" location="/css/**"/>      这些资源不拦截

自定义类型转换器

必须实现Converter<S,T>并重写convert方法

public class StringToDate implements Converter<String, Date> {@Overridepublic Date convert(String source) {if (source == null) {System.err.println("参数不能为空");throw new RuntimeException();}Date parse = null;try {parse = new SimpleDateFormat("yyyy-MM-dd").parse(source);} catch (ParseException e) {System.err.println("输入的参数无法转换");throw new RuntimeException();}return parse;}
}

配置自定义类型转换器

 <!--自定义类型转换器-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">   <property name="converters"><set><bean class="cn.le.Converter.StringToDate"></bean></set></property></bean><!--springMVC注解的支持,将自己的代码也生效的配置--><mvc:annotation-driven conversion-service="conversionService"/>

springMVC的特殊操作

获取Servlet的原生对象

public String sayHello(HttpServletRequest req, HttpServletRequest res) {  直接放在参数里,就能调用

参数不一致导致无法封装解决

@RequestMapping(value = "/hello11")
public String sayHello11(@RequestParam("name=username")String name) {     如果前端参数不一致加这个注解
@RequestMapping(value = "/hello11")
public String sayHello11(@RequestParam(required=true) String name) {      必须和方法里的参数一致,不然报错

获取整个请求体

@RequestMapping(value = "/hello12")                                       这个是请求体:user=321&age=312
public String sayHello12(@RequestBody String body) {                      通过这个注解直接获取后端发送的完整请求体(get不行)

使用restful风格

@RequestMapping("/hello13/{uid}")                                         前端的href为href="hello13/10,获取到uid为10,并赋值给id
public String sayHello13(@PathVariable(name ="uid") String id) {          @PathVariabl注解通过name找到对应{}内的值

获取请求头

@RequestMapping("/hello14")
public String sayHello14(@RequestHeader("Accept") String Accept) {        通过这个注解获取请求头Accept

获取指定cookie

@RequestMapping("/hello15")
public String sayHello15(@CookieValue("JSESSIONID") String JSESSIONID) { 通过这个注解获取指定名称的cookie

@ModelAttribute注解

有返回值用法
@RequestMapping("/hello16")                      
public String sayHello16(User user) {                接收到下面方法的userreturn "success";}
@ModelAttribute                                      即使没调用这个方法,有了@ModelAttribute注解这个方法总是会执行,并且先执行                                 
public User say(String uname) {                      一个表单可能无法为实体类的所有元素赋值,先从数据库里查出来并赋值,然后在调用hello6将其中的部分参数覆盖         
User user=(数据库执行操作)                                               return user;}
无返回值用法
@RequestMapping("/hello16")
public String sayHello17(@ModelAttribute("abc") User user) { 从下面的Map集合中取System.out.println("我执行sayHello");return "success";}
@ModelAttribute
public void say2(String username, Map<String, User> map) {  将user存入Map集合中System.out.println("我执行说");User user=(数据库执行操作)map.put("abc", user);}

共享参数

@SessionAttributes(value = "msg")                         再在类上写上这个注解代表将从request与中取出再存入session域中
public class helloController {
@RequestMapping("/hello18")
public String sayHello18(Model model) {                   先存入Model里的键值对会被springMVC存入request域中System.out.println("我执行sayHello");model.addAttribute("msg", "123");return "success";}

控制器无返回值用法

@RequestMapping("/test")
public void test() {                                     如果是无返回值方法那么会跳转到请求路径上                       System.out.println("进入了");                        如<a href="test">点击</a>会跳转到test这个路径下当然也可以使用HttpServlet原生API来进行跳转(跳过视图解析器,自己写代码)

不使用视图解析器转发

方法返回值写成这样就行了return "forward:/WEB-INF/pages/success.jsp";            转发写法return "redirect:/index.jsp";                           重定向写法

ModelAndView

@RequestMapping("/test3")
public ModelAndView test3(){
ModelAndView mv=new ModelAndView();
mv.addObject("user",user);                               用ModelAndView存入request域中
mv.setViewName("success");                               用ModelAndView跳转指定页面return mv;

获取ajax请求(需要jackson的jar包)

直接获取用@RequestBody
@RequestMapping("/testAjax")
public @ResponseBody User testAjax(@RequestBody User user){ @ResponseBody可以写在返回值类型里也可以写在参数里springMVC会自动转换为jackson或ajax请求

*返回值如果是字符串为地址,是实体类为json数据

文件上传

准备HTML页面

<a href="response.jsp">啦啦啦</a>
<form action="" method="post" enctype="multipart/form-data">      enctype的值使form表单能传递文件选择文件<input type="file" name="upload"/><input type="submit" value="上传文件"/>
</form>

不使用springMVC(需要commons-fileupload和commons-io的jar包)

  @RequestMapping("/file")public String testFile(HttpServletRequest req) {//通过req获取session,通过session获取最大域对象context,然后获取指定路径String path = req.getSession().getServletContext().getRealPath("/uploads");File file = new File(path);//判断是否存在if (!file.exists()) {file.mkdirs();}//获取commons-fileupload的工厂类DiskFileItemFactory factory = new DiskFileItemFactory();//获取实现上传的类ServletFileUpload upload = new ServletFileUpload(factory);List<FileItem> fileItems = null;try {//解析req,获取文件项fileItems = upload.parseRequest(req);} catch (FileUploadException e) {e.printStackTrace();}//遍历for (FileItem f : fileItems) {//如果不是普通表单,那就是上传文件的表单if (!f.isFormField()) {String name = f.getName();try {f.write(new File(path, name));//删除临时文件f.delete();} catch (Exception e) {e.printStackTrace();}}}return "success";}

springMVC的上传方式
使用MultipartFile

 @RequestMapping("/springMVC")public String testFile2(HttpServletRequest req, MultipartFile upload) { //必须要和表单的name属性一致//通过req获取session,通过session获取最大域对象context,然后获取指定路径String path = req.getSession().getServletContext().getRealPath("/uploads");File file = new File(path);//判断是否存在if (!file.exists()) {file.mkdirs();}String fileName = upload.getOriginalFilename();try {//移动到新的地方upload.transferTo(new File(path, fileName));} catch (IOException e) {e.printStackTrace();}return "success";}

配置springMVC

 <!--配置文件解析器对象--><bean id="multipartResolver" class="org.springframework.web.multipartmons.CommonsMultipartResolver"><property name="maxInMemorySize" value="10485760"/></bean>

更多推荐

springMVC个人笔记

本文发布于:2024-02-27 20:53:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1766363.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:笔记   springMVC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!