spring mvc 返回方式
package com.boventech.learning.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.boventech.learning.entity.User;
/**
* MVCReturn
* @author peng.xia
*
*/
@Controller
@RequestMapping("/MVCReturn")
public class SpringMVCReturnController {
@RequestMapping(value="/index1",method=RequestMethod.GET)
public ModelAndView index(){
ModelAndView modelAndView = new ModelAndView("/user/index");
modelAndView.addObject("name", "xxx");
return modelAndView;
}
对于ModelAndView构造函数可以指定返回页面的名称,也可以通过setViewName方法来设置所需要跳转的页面;
@RequestMapping(value="/index2",method=RequestMethod.GET)
public ModelAndView index2(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", "xxx");
modelAndView.setViewName("/user/index");
return modelAndView;
}
//返回的是一个包含模型和视图的ModelAndView对象;
/**
* Model一个模型对象,
* 主要包含spring封装好的model和modelMap,以及java.util.Map,
* 当没有视图返回的时候视图名称将由requestToViewNameTranslator决定;
* @return
*/
@RequestMapping(value="/index3",method=RequestMethod.GET)
public Map<String, String> index3(){
Map<String, String> map = new HashMap<String, String>();
map.put("1", "1");
//map.put相当于request.setAttribute方法
return map;
}
//响应的view应该也是该请求的view。等同于void返回。
//返回String
//通过model进行使用
@RequestMapping(value="/index4",method = RequestMethod.GET)
public String index(Model model) {
String retVal = "user/index";
User user = new User();
user.setName("XXX");
model.addAttribute("user", user);
return retVal;
}
//通过配合@ResponseBody来将内容或者对象作为HTTP响应正文返回(适合做即时校验);
@RequestMapping(value = "/valid", method = RequestMethod.GET)
@ResponseBody
public String valid(@RequestParam(value = "userId", required = false) Integer userId,
@RequestParam(value = "name") String name) {
return String.valueOf(true);
}
//返回字符串表示一个视图名称,这个时候如果需要在渲染视图的过程中需要模型的话,就可以给处理器添加一个模型参数,然后在方法体往模型添加值就可以了,
@RequestMapping(method=RequestMethod.GET)
public void index5(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("xxx", "xxx");
}
//返回的结果页面还是:/type
//这个时候我们一般是将返回结果写在了HttpServletResponse 中了,如果没写的话,
//spring就会利用RequestToViewNameTranslator 来返回一个对应的视图名称。如果这个时候需要模型的话,处理方法和返回字符串的情况是相同的。
}
@Controller
public class RequestController{
@RequestMapping("/resp")
public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
resp.getWriter().println("hello HttpServletResponse");
}
### 1.2 使用HttpServletResponse 重定向到另一个视图(其他不变 )
@RequestMapping("/resp")
public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
resp.sendRedirect("index.jsp");
}
@RequestMapping("/resp")
public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.setAttribute("message","it's forword ");
req.getRequestDispatcher("index.jsp").forward(req,resp);
}
@RequestMapping("/nice")
public String hello1(){
//转发方式1
return "home.jsp";
//转发方式2
return "forward:index.jsp";
//重定向方式
return "redirect:index.jsp";
}
@RequestMapping("/nice")
public String hello1(){
//转发方式1
return "home";
//转发方式2
return "forward:index";
//重定向方式 hello指的是requsrmapping
return "redirect:hello";
}
###2.1 使用modelandview 需要视图解析器 能指定跳转页面
@Override
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest,
javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
//封装要显示到视图的数据
mv.addObject("msg","hello myfirst mvc");
//视图名
mv.setViewName("hello");
return mv;
}
不需要视图解析器 不能指定跳转页面
//通过modelmap方式
@RequestMapping("/modelmap")
public String modelHello(String name,ModelMap map){
map.addAttribute("name",name);
System.out.println(name);
return "index.jsp";
}
@RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET)
public String printMessage1(@PathVariable String id,@PathVariable String name, ModelMap model) {
System.out.println(id);
System.out.println(name);
model.addAttribute("message", "111111");
return "users";
}
JSP表单如下
<form method="post" action="hao.do">
a: <input id="a" type="text" name="a"/>
b: <input id="b" type="text" name="b"/>
<input type="submit" value="Submit" />
</form>
Java Pojo如下
public class Pojo{
private String a;
private int b;
}
Java Controller如下
@RequestMapping(method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pojo") Pojo pojo) {
return "helloWorld";
}
@RequestMapping(method = RequestMethod.GET)
public String get(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getParameter("a"));
return "helloWorld";
}
用注解@RequestParam绑定请求参数a到变量a
当请求参数a不存在时会有异常发生,可以通过设置属性required=false解决,
例如: @RequestParam(value="a", required=false)
Controller如下
@RequestMapping(value = "/requestParam", method = RequestMethod.GET)
public String setupForm(@RequestParam("a") String a, ModelMap model) {
System.out.println(a);
return "helloWorld";
}
/**
* 1.直接把表单的参数写在Controller相应的方法的形参中
* @param username
* @param password
* @return
*/
@RequestMapping("/addUser1")
public String addUser1(String username,String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
/**
* 2、通过HttpServletRequest接收
* @param request
* @return
*/
@RequestMapping("/addUser2")
public String addUser2(HttpServletRequest request) {
String username=request.getParameter("username");
String password=request.getParameter("password");
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
package demo.model;
public class UserModel {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
/**
* 3、通过一个bean来接收
* @param user
* @return
*/
@RequestMapping("/addUser3")
public String addUser3(UserModel user) {
System.out.println("username is:"+user.getUsername());
System.out.println("password is:"+user.getPassword());
return "demo/index";
}
/**
* 4、通过@PathVariable获取路径中的参数
* @param username
* @param password
* @return
*/
@RequestMapping(value="/addUser4/{username}/{password}",method=RequestMethod.GET)
public String addUser4(@PathVariable String username,@PathVariable String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
<form action ="<%=request.getContextPath()%>/demo/addUser5" method="post">
用户名: <input type="text" name="username"/><br/>
密 码: <input type="password" name="password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>
/**
* 5、使用@ModelAttribute注解获取POST请求的FORM表单数据
* @param user
* @return
*/
@RequestMapping(value="/addUser5",method=RequestMethod.POST)
public String addUser5(@ModelAttribute("user") UserModel user) {
System.out.println("username is:"+user.getUsername());
System.out.println("password is:"+user.getPassword());
return "demo/index";
}
当请求参数username不存在时会有异常发生,可以通过设置属性required=false解决,例如: @RequestParam(value="username", required=false)
/**
* 6、用注解@RequestParam绑定请求参数到方法入参
* @param username
* @param password
* @return
*/
@RequestMapping(value="/addUser6",method=RequestMethod.GET)
public String addUser6(@RequestParam("username") String username,@RequestParam("password") String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "demo/index";
}
@RequestMapping(value = "YL1101")
@ResponseBody
public String getOrderNo(HttpServletRequest request) {
String msg = request.getParameter(MessageConstants.REQ_MESSAGE);
log.info("获取订单号交易开始...");
log.info("请求数据为:{}", msg);
ReqMsg reqmessage = null;
RspMsg rspmessage = new RspMsg();
try {
reqmessage = Msg.getReqMessage(msg);
Map<String, Object> pmap = reqmessage.getBody();
String orderNo = service.getOrderNo(pmap);
rspmessage.setDataV("orderNo", orderNo);
rspmessage.setDataV("RSPCOD", "000000");
rspmessage.setDataV("RSPMSG", "获取订单号成功");
} catch (TranException e) {
rspmessage.setDataV("RSPCOD", e.getCode());
rspmessage.setDataV("RSPMSG", e.getMsg());
log.error(e.getMessage(), e);
}
log.info("获取订单号交易完成.");
return Msg.getRspJson(rspmessage);
}
/**
* 修改
*/
@RequestMapping(value = "/edit")
public ModelAndView edit() throws Exception {
logBefore(logger, "修改BusinessInf");
if (!Jurisdiction.buttonJurisdiction(menuUrl, "edit")) {
return null;
} // 校验权限
ModelAndView mv = this.getModelAndView();
PageData pd = new PageData();
pd = this.getPageData();
businessinfService.edit(pd);
mv.addObject("msg", "success");
mv.setViewName("save_result");
return mv;
}
public ModelAndView getModelAndView(){
return new ModelAndView();
}
/**
* 得到request对象
*/
public HttpServletRequest getRequest() {
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
return request;
}
/**
* 得到PageData
*/
public PageData getPageData(){
return new PageData(this.getRequest());
}
==================以上两种皆为从request取参数==============
为了使用占位符,我们必须要配置一个 PropertyPlaceholderConfigurer bean 或 PropertySourcesPlaceholderConfigurer bean 。从 Spring 3.1 开始,推荐使用 PropertySourcesPlaceholderConfigurer ,因为它能够基于 Spring Environment 及其属性源来 解析占位符。 @Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } <context:property-placeholder /> <context:property-placeholder location="classpath:conf/jdbc.properties" />
quartz 定时配置 "0 0 12 * * ?" 每天中午12点触发 "0 15 10 ? * *" 每天上午10:15触发 "0 15 10 * * ?" 每天上午10:15触发 "0 15 10 * * ? *" 每天上午10:15触发 "0 15 10 * * ? 2005" 2005年的每天上午10:15触发 "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 * ?" 每月15日上午10:15触发 "0 15 10 L * ?" 每月最后一日的上午10:15触发 "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
============================================================================================== 基本两种使用方法 ##1.xml配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
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/tx
http://www.springframework.org/schema/tx/spring-tx-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/util
http://www.springframework.org/schema/util/spring-util-3.2.xsd
">
<!-- 可单独配置数据源 -->
<context:component-scan base-package="com.webimation.boss.service" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>${jdbc_driverClassName}</value>
</property>
<property name="url">
<value>${jdbc_url}</value>
</property>
<property name="username">
<value>${jdbc_username}</value>
</property>
<property name="password">
<value>${jdbc_password}</value>
</property>
<!-- 连接池最大使用连接数 -->
<property name="maxActive">
<value>${jdbc_maxActive}</value>
</property>
<!-- 初始化连接大小 -->
<property name="initialSize">
<value>${jdbc_initialSize}</value>
</property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait">
<value>${jdbc_maxWait}</value>
</property>
<!-- 连接池最大空闲 (DruidDataSource 中已弃用) <property name="maxIdle"> <value>20</value>
</property> -->
<!-- 连接池最小空闲 -->
<property name="minIdle">
<value>${jdbc_minIdle}</value>
</property>
<!-- 自动清除无用连接 -->
<property name="removeAbandoned">
<value>${jdbc_removeAbandoned}</value>
</property>
<!-- 清除无用连接的等待时间 -->
<property name="removeAbandonedTimeout">
<value>${jdbc_removeAbandonedTimeout}</value>
</property>
<!-- 连接属性 -->
<property name="connectionProperties">
<value>${jdbc_connectionProperties}</value>
</property>
</bean>
<!-- mybatis文件配置,扫描所有mapper文件 -->
<bean name="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="classpath:conf/mybatis-config-merBoss.xml"
p:mapperLocations="classpath:conf/mappers/*.xml" />
<!-- 扫描指定dao -->
<bean name="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="com.webimation.boss.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" />
<!-- 定义jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean name="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 以下的方法声明了是否需要事务,注意如果自己的方法命名不在事务声明的方法中,需要增加 -->
<tx:method name="delete*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="insert*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="update*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="save*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<tx:method name="add*" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- 事物处理 -->
<aop:config>
<aop:pointcut id="pc"
expression="execution(* com.webimation.boss.service.*.*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
</aop:config>
<tx:method name="*Transaction" propagation="REQUIRED" read-only="false"
rollback-for="java.lang.Exception" />
<aop:config>
<aop:pointcut id="pc"
expression="execution(* com.webimation.boss.service.*.*(..))" />
<aop:advisor pointcut-ref="pc" advice-ref="txAdvice" />
</aop:config
其中第一个代表返回值,第二代表service下子包,第三个*代表方法名,“(..)”代表方法参数。
其中第一个代表返回值,第二代表service下子包,第三个*代表方法名,“(..)”代表方法参数。
在此声明适用范围,可把需要事务的交易放在一个包中,方便管理
A.方法前加声明 @Transactional(propagation = Propagation.REQUIRED) public void addBusiAndMer(MerchantInf mer,BusinessInf binf) { merchantInfoService.insert(mer); businessInfoService.insert(binf); } B.xml中增加如下配置 <tx:annotation-driven transaction-manager="transactionManager" />
需要设置活跃配置文件
可通过 system properties, environment variables, or JNDI 来设置,级别高于spring.profiles.default
需要在web.xml中设置,注意两个地方
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
@primary @component 指定一个首选类,但指定多个时会带来问题 @Qualifier("iceCream") all beans are given a default qualifier that’s the same as their bean ID,if ID not defined,then the name of className is given with the initial letter lowercased. @Component @Qualifier("cold")
@Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)--为每个注入新建一个实例 ===============================SpEl=========================== #{systemProperties['disc.title']} #{9.87E4}=98700 #{'Hello'} #{false} #{artistSelector.selectArtist()?.toUpperCase()} #{T(java.lang.Math)}=Java’s Math class #{scoreboard.score > 1000 ? "Winner!" : "Loser"} #{disc.title ?: 'Rattle and Hum'} if disc.title is null,return 'Rattle and Hum' #{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.com'} #{jukebox.songs[4].title} #{jukebox.songs[T(java.lang.Math).random() * To spice things up a bit 稍微加点料 jukebox.songs.size()].title} #{jukebox.songs.?[artist eq 'Aerosmith']} #{jukebox.songs.^[artist eq 'Aerosmith']} 取符合条件的第一个 #{jukebox.songs.$[artist eq 'Aerosmith']} 取符合条件的最后一个 #{jukebox.songs.![title]} 所有title属性的集合 ,#{jukebox.songs.?[artist eq 'Aerosmith'].![title]}
@TestPropertySource("/test.properties") @ActiveProfiles({"dev", "test"}) 注意:是最后一个配置起作用 @ContextHierarchy({ @ContextConfiguration(classes = TestConfig.class), @ContextConfiguration(classes = WebConfig.class) }) @DirtiesContext @TestExecutionListeners @Timed(millis=2000) must finish in 2 seconds
@Repeat(100) exec 100 times
Interceptor是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean类型的,当它返回为false 时,表示请求结束,后续的Interceptor和Controller 都不会再执行;当返回值为true时就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法 postHandle (HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView) 方法,由preHandle 方法的解释我们知道这个方法包括后面要说到的afterCompletion 方法都只能是在当前所属的Interceptor 的preHandle 方法的返回值为true 时才能被调用。postHandle 方法,顾名思义就是在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行
(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex) 方法,该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
解决:
mvc:annotation-driven mvc:message-converters </mvc:message-converters> </mvc:annotation-driven>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。