赞
踩
属于web层开发技术
1.导入pom.xml坐标
2.把要调用的方法设置成bean
因为是在web层,所以要设置成controller
usercontroller上面加上@Controller标签
里面写方法,上面加上标签:@RequestMapping
@ResponseBody
3.初始化一个springmvcConfig的配置类,专门用来加载springmvc的控制器
- @Configuration
- @Component("com.itheima.controller")
- public class SpringMvcConfig{
-
- }
4.加载SpringMvc环境,并且用mvc技术解决问题
- public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
- //加载springmvc配置类,产生springmvc容器(本质还是spring容器)
- protected WebApplicationContext createServletApplicationContext() {
- //初始化WebApplicationContext对象
- AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
- //加载指定配置类
- ctx.register(SpringMvcConfig.class);
- return ctx;
- }
-
- //设置由springmvc控制器处理的请求映射路径
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
-
- //加载spring配置类
- protected WebApplicationContext createRootApplicationContext() {
- return null;
- }
- }

很方便,因为controller下面可以写很多方法,除了第一个案例要配置的东西有点多之外,其他都还好
3.SpringMvc案例的流程分析
springmvc正常配置就好了
spring要注意一点
就com.itheima和Controller.class需要改一改
- //@ComponentScan({"com.itheima.service","com.itheima.dao"})
- //设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
- //excludeFilters属性:设置扫描加载bean时,排除的过滤规则
- //type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
- //classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
-
- @ComponentScan(value="com.itheima",
- excludeFilters = @ComponentScan.Filter(
- type = FilterType.ANNOTATION,
- classes = Controller.class
- )
- )
在一开始引入springmvc环境的时候还有一种简单的方法
- public class ServlectContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
-
- //root配置的是spring
- protected Class<?>[] getRootConfigClasses() {
- return new Class[]{SpringConfig.class};
- }
-
- //ServletConfig配置的是SpringMvc
- protected Class<?>[] getServletConfigClasses() {
- return new Class[]{SpringMvcConfig.class};
- }
-
- //配置的是全部路径
- protected String[] getServletMappings() {
- return new String[]{"/"};
- }
- }

可以用来发post或者get请求
避免多个控制器重名的问题:
在控制器上面加上前缀就好了
- @RequestMapping("/user")
- public class UserController {
- //请求路径映射
- @RequestMapping("/save")
- @ResponseBody
- public String save(){
- System.out.println("user save ...");
- return "{'module':'user save'}";
- }
- //请求路径映射
- @RequestMapping("/delete")
- @ResponseBody
- public String delete(){
- System.out.println("user delete ...");
- return "{'module':'user delete'}";
- }
-
- }

突然反应过来get和post对于mvc来说是一起接收的吗??没有doget和dopost之分????
太牛啦!!!!!
直接在下面写就好
在一开始初始化的config里面加一个过滤器
- //乱码处理
- @Override
- protected Filter[] getServletFilters() {
- CharacterEncodingFilter filter = new CharacterEncodingFilter();
- filter.setEncoding("UTF-8");
- return new Filter[]{};
- }
第一种:名字不匹配可以强行让它匹配
- @RequestMapping("/commonParamDifferentName")
- @ResponseBody
- public String commonParamDifferentName(@RequestParam("name") String userName , int age){
- System.out.println("普通参数传递 userName ==> "+userName);
- System.out.println("普通参数传递 age ==> "+age);
- return "{'module':'common param different name'}";
- }
第二种:类,直接对着它的名字传就好了
- //POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
- @RequestMapping("/pojoParam")
- @ResponseBody
- public String pojoParam(User user){
- System.out.println("pojo参数传递 user ==> "+user);
- return "{'module':'pojo param'}";
- }
第三种:数组传参,直接全部传一个变量名就行了,名字写同一个就好了
- //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
- @RequestMapping("/arrayParam")
- @ResponseBody
- public String arrayParam(String[] likes){
- System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
- return "{'module':'array param'}";
- }
第四种:传集合
固定搭配
@RequestParam List<String> likes
注意,list是可以重复的
1.springmvconfig上面加上标签
@EnableWebMvc
2.每一个传递json参数的变量前面,都要加上
@RequestBody
list数组是[]
user类对象是 {}
直接这样传递就好了
几种日期格式:
- @RequestMapping("/dataParam")
- @ResponseBody
- public String dataParam(Date date,
- @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
- @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2
- ){
- System.out.println("参数传递 date ==> "+date);
- System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
- System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
- return "{'module':'data param'}";
- }
记得一点:@DateTimeFormat的标签
括号里面写Pattern写的格式,要和你发送请求的格式相同,要不然匹配不上
为什么可以起到转换的作用呢?底层原理是用到了一个接口
最重要的是,如果想要起到转换器的作用的话,要在springmvconfig里面加上标签
1.除了页面跳转直接写String然后直接返回地址外
2.其他都是加上@responsebody标签
然后返回值的类型选对应想返回的东西就行了
responsebody标签,可以将对象数据转换成JSON数据,然后返回,主要是用到一个接口
要想转换,记得加jkson坐标
12.restful风格代码
1.requestmethod
- @RequestMapping(value = "/users",method = RequestMethod.POST)
- @ResponseBody
- public String save(){
- System.out.println("user save...");
- return "{'module':'user save'}";
- }
2.在路径中要接收参数
{}
@pathVarible
- @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
- @ResponseBody
- public String delete(@PathVariable Integer id){
- System.out.println("user delete..." + id);
- return "{'module':'user delete'}";
- }
1.controller
- @RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
- @RequestMapping("/books")
- public class BookController {
2.代替requestmapping的四个简易标签
- @PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
- public String save(@RequestBody Book book){
- System.out.println("book save..." + book);
- return "{'module':'book save'}";
- }
-
- // @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
- @DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
- public String delete(@PathVariable Integer id){
- System.out.println("book delete..." + id);
- return "{'module':'book delete'}";
- }
-
- // @RequestMapping(method = RequestMethod.PUT)
- @PutMapping //使用@PutMapping简化Put请求方法对应的映射配置
- public String update(@RequestBody Book book){
- System.out.println("book update..."+book);
- return "{'module':'book update'}";
- }
-
- // @RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
- @GetMapping("/{id}") //使用@GetMapping简化GET请求方法对应的映射配置
- public String getById(@PathVariable Integer id){
- System.out.println("book getById..."+id);
- return "{'module':'book getById'}";
- }

静态类应该直接放行,不用经过springmvc
domain
dao:增删改查语句
BookService接口:复制dao里面java语句过去就行了,把对应的功能用日记的形式记录
BookServiceImpl实现类:在实现类上加上@Service标签,并且在语句中自动装配bookdao,重写方法调用bookdao的方法
BookController:类上加上@RestController标签,@RequestMappering("/books)表明映射路径。自动装配@Autowired bookService ,调用bookService里面的方法。在每个方法上面加上标签,表明@PostMapping或者其他等等。1.有id的加上("/{id}")和@PathVerible 2.有实体类的加上@RequestBody
业务层用junit:
用
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes =SpringConfig.class)标签
@TEST
- @Autowired
- private BookService bookService;
-
- @Test
- public void testGetById(){
- Book by = bookService.getById(1);
- System.out.println(by);
-
- }
表现层用postman
注意修改的时候要给出id的号,别写个Null在那修改
问题分析:
@PropertySource("jdbc.properties") 错误
未能在[com.ssm.config.SpringConfig]的类中找到相关的[/jdbc.properties]文件。
解决方案:
在Spring配置类改写注解为@PropertySource("classpath:jdbc.properties")即可。
事务管理:
1.开始注解式事务驱动在springconfig上面@EnableTransactionManagement
2.事务平台管理器在jdbcConfig处理
- @Bean
- public PlatformTransactionManager platformTransactionManager(DataSource dataSource){
- DataSourceTransactionManager ds = new DataSourceTransactionManager();
- ds.setDataSource(dataSource);
- return ds;
- }
3.在BookService上面加上@Transactional挂上事务
就是要有
Integer code:表示状态
Object data:表示保存的对象
String msg:表示语句
Controller里面创建:
code里面放常量:
- package com.itheima.controller;
-
- public class Code {
- // public static final Integer SAVE_OK = ;
- public static final Integer SAVE_OK=20011;
- public static final Integer DELETE_OK=20021;
- public static final Integer UPDATA_OK=20031;
- public static final Integer GET_OK=20041;
-
- public static final Integer SAVE_ERR=20010;
- public static final Integer DELETE_ERR=20020;
- public static final Integer UPDATA_ERR=20030;
- public static final Integer GET_ERR=20040;
-
- }
Result里面放变量和构造方法:
- package com.itheima.controller;
-
- public class Result {
- private Object data;
- private Integer code;
- private String msg;
-
- public Result() {
- }
-
- public Result(Integer code,Object data) {
- this.data = data;
- this.code = code;
- }
-
- public Result( Integer code, Object data,String msg) {
- this.data = data;
- this.code = code;
- this.msg = msg;
- }
-
- public Object getData() {
- return data;
- }
-
- public void setData(Object data) {
- this.data = data;
- }
-
- public Integer getCode() {
- return code;
- }
-
- public void setCode(Integer code) {
- this.code = code;
- }
-
- public String getMsg() {
- return msg;
- }
-
- public void setMsg(String msg) {
- this.msg = msg;
- }
- }

然后再controller里面就可以调用了,表现层封装result
- @GetMapping
- public Result getAll() {
- // System.out.println("getall.....");
- List<Book> all = bookService.getAll();
- Integer code= all!=null?Code.GET_OK:Code.GET_ERR;
- String msg= all!=null?"":"查询失败";
- return new Result(code,all,msg);
- }
提供了一个类,作为异常处理器
在controller包下新建,ProjectExceptionAdvise
加上@RestControllerAdvise
写个方法加上@ExceptionHandler()括号里面是拦截的类型
写的方法注意是Result返回类型,要不然前面接收不到
- @RestControllerAdvice
- public class ProjectExceptionAdvise {
-
- @ExceptionHandler(Exception.class)
- public Result doException(Exception ep){
- System.out.println("hhhh,异常啦......");
- return new Result(666,null,"异常啦");
- }
- }
项目异常分类:
1.创建一个exception包
里面放两个类
2.设定异常编码code,在之前的code里面加就行了
3.将可能出现的异常进行包装,包装成我们自己写的异常
在service里面
- if(id==1){
- throw new BusinessException(Code.BUSINESS_ERR,"输入的不对哦");
- }
- try{
- int i=1/0;
- }catch (Exception e){
- throw new SystemException(Code.SYSTEM_ERR,"服务器异常",e);
- }
4.在异常拦截器里面统一处理我们写的分类异常
- @ExceptionHandler(SystemException.class)
- public Result doSystemException(SystemException ex){
-
- //记录日志
- //发送消息给运维
- //发送消息给开发人员,并发送异常ex
- System.out.println("hhhh,异常啦......");
- return new Result(ex.getCode(),null,ex.getMessage());
- }
-
- @ExceptionHandler(BusinessException.class)
- public Result doBusinessException(BusinessException ex){
- System.out.println("hhhh,异常啦......");
- return new Result(ex.getCode(),null,ex.getMessage());
- }
1.继承WebMvcConfigurationSupport
2.重写addResourceHandlers
3.定向registry.addResourceHandler.().addResourceLocation();(注意后面地址有个/)
- @Configuration
- public class SpringMvcSupport extends WebMvcConfigurationSupport {
- @Override
- protected void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
- registry.addResourceHandler("/css/**").addResourceLocations("/css/");
- registry.addResourceHandler("/js/**").addResourceLocations("/js/");
- registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
- }
- }
最后SpringMvcConfig扫描到它即可
注意support里面加@
- getAll() {
- axios.get("/books").then((res)=>{
- this.dataList=res.data.data;
- })
- }
1.弹出添加页面
- //弹出添加窗口
- handleCreate() {
- this.dialogFormVisible=true;
- }
2.前端发送请求添加数据。
这里就是相当于往数据库里面添加了。
然后对前端页面进行修改,这段代码的意思是:当点击添加页面提交按钮键,提交表单上面的信息到后端(就相当于我们postman进行提交数据,只是这里在前端页面进行操作了);然后关闭前端页面;再调用getAll。
- //添加
- handleAdd () {
- axios.post("/books",this.formData).then((res)=>{
- this.dialogFormVisible=false;
- this.getAll();
- })
- }
- //添加
- handleAdd () {
- axios.post("/books",this.formData).then((res)=>{
-
- console.log(res.data);
-
- if(res.data.code==20011){
- this.dialogFormVisible=false;
- this.$message.success("添加成功");
- }else if(res.data.code==20010){
-
- this.$message.error("添加失败");
- }else{
- this.$message.error(res.data.msg);
- }
-
- }).finally(()=>{
- this.getAll();
- })
- },

通过影响行计数,来观察添加是否成功
console.log(res.data);可以用来在前端观察后端发来的数据
真的无语,把error写成err,一直不弹窗,一直debug
在打开提交表单的时候,要把formdata清空
- //弹出添加窗口
- handleCreate() {
- this.dialogFormVisible=true;
- this.resetForm();
- },
-
- //重置表单
- resetForm() {
- this.formData={};
- },
弹出编辑窗口
- //弹出编辑窗口
- handleUpdate(row) {
- //先根据id查询数据,把数据绑定到表单上
- axios.get("/books/"+row.id).then((res)=>{
- if(res.data.code==20041){
- this.dialogFormVisible4Edit=true;
-
- this.formData=res.data.data;
- }else{
- this.$message.error(res.data.msg);
- }
-
- })
- },
编辑
- //编辑
- handleEdit() {
- axios.put("/books",this.formData).then((res)=>{
- // console.log(res.data);
- if(res.data.code==20031){
- this.dialogFormVisible=false;
- this.$message.success("修改成功");
- }else if(res.data.code==20030){
-
- this.$message.error("修改失败");
- }else{
- this.$message.error(res.data.msg);
- }
- }).finally(()=>{
- this.getAll();
- })
- },

- // 删除
- handleDelete(row) {
- // axios.delete("/books/"+row.id).then((res)=>{
- // if(res.data.code==20021){
- // // this.dialogFormVisible=false;
- // this.$message.success("删除成功");
- // }else if(res.data.code==20020){
- //
- // this.$message.error("删除失败");
- // }else{
- // this.$message.error(res.data.msg);
- // }
- // }).finally(()=>{
- // this.getAll();
- // })
- this.$confirm("此操作永久删除","提示",{
- type:'info'
- }).then(()=>{
- //删除
- axios.delete("/books/"+row.id).then((res)=>{
- if(res.data.code==20021){
- // this.dialogFormVisible=false;
- this.$message.success("删除成功");
- }else if(res.data.code==20020){
-
- this.$message.error("删除失败");
- }else{
- this.$message.error(res.data.msg);
- }
- });
-
- }).catch(()=>{
- //取消
- this.$message.info("取消删除操作");
- }).finally(()=>{
- this.getAll();
- });
- }
- }

在controller下面创建一个interception包,在里面创建java类来重写三个抽象方法。
加上component标签,让springmvcconfig扫描到它
- @Component
- public class ProjectInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- // return HandlerInterceptor.super.preHandle(request, response, handler);
- System.out.println("preHandle.....");
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- // HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
- System.out.println("postHandle....");
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- // HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
- System.out.println("afterCompletion....");
- }
- }

然后在springmvcsupport放行。当访问books的时候,拦截器进行拦截
- @Configuration
- public class SpringMvcSupport extends WebMvcConfigurationSupport {
- @Override
- protected void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
- registry.addResourceHandler("/css/**").addResourceLocations("/css/");
- registry.addResourceHandler("/js/**").addResourceLocations("/js/");
- registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
- }
- @Autowired
- private ProjectInterceptor projectInterceptor;
- @Override
- protected void addInterceptors(InterceptorRegistry registry) {
- // super.addInterceptors(registry);
- //当调用books请求的时候,拦截
- registry.addInterceptor(projectInterceptor).addPathPatterns("/books");
- }
- }

注意springmvcsupport和projectinterceptor都要在springmvcconfig里面放行
想要拦截多个路径,在后面接着写就行了
registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
preHandle里面写false,就无法继续往下走了
第三个可以获得我们执行的参数
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- String contentType = request.getHeader("Content-Type");
- HandlerMethod hm = (HandlerMethod)handler;
- System.out.println("preHandle..."+contentType);
- return true;
- }
第四个,页面跳转
- @Override
- //原始方法调用后执行的内容
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- System.out.println("postHandle...");
- }
第四个,捕捉异常
- @Override
- //原始方法调用完成后执行的内容
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- System.out.println("afterCompletion...");
- }
总的来说是preHandle里面的return false;return true最有用
拦截顺序和你配置在support里面的顺序有关
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。