在这里,我们将给大家分享关于HTTP400的SpringMVC自定义消息的知识,让您更了解springmvc自定义参数解析的本质,同时也会涉及到如何更有效地HTTP状态405-具有SpringSecu
在这里,我们将给大家分享关于HTTP 400的Spring MVC自定义消息的知识,让您更了解springmvc自定义参数解析的本质,同时也会涉及到如何更有效地HTTP状态405-具有Spring Security的Spring MVC不支持请求方法'POST'、java – 用于HTTP 400的Spring MVC自定义消息、JavaEE开发之SpringMVC中的自定义消息转换器与文件上传、Java框架-Spring MVC理解003-spring MVC自身的创建的内容。
本文目录一览:- HTTP 400的Spring MVC自定义消息(springmvc自定义参数解析)
- HTTP状态405-具有Spring Security的Spring MVC不支持请求方法'POST'
- java – 用于HTTP 400的Spring MVC自定义消息
- JavaEE开发之SpringMVC中的自定义消息转换器与文件上传
- Java框架-Spring MVC理解003-spring MVC自身的创建
HTTP 400的Spring MVC自定义消息(springmvc自定义参数解析)
我下面有几种SprigMVC方法,返回ModelAndView或Responsebody。当用户向这些网址请求缺少必需参数的请求时,他们自然会收到消息
“不存在必需的字符串参数’id’” 。
从安全角度来看,我想向用户 隐藏此详细描述消息
。因此,黑客不容易知道丢失的参数,并且会在没有任何描述的情况下得到400错误。这是可以通过spring配置/ Spring
Security实现的,还是我必须手动重构所有方法才能以某种方式返回自定义消息。
@RequestMapping(value = "/payment", method = RequestMethod.GET)public ModelAndView getReponse(@RequestParam(value = "id", required = true)) { return model;}@RequestMapping(value = "/status", method = RequestMethod.GET)public @ResponseBody String getStatus(@RequestParam(value = "id", required = true) String id) { return "string";}
答案1
小编典典您真正需要的是MissingServletRequestParameterException的全局处理程序,当缺少请求参数时,Spring会抛出该全局处理程序。解决此问题的最简单方法是使用ControllerAdvice,它将对所有控制器进行处理。
import org.springframework.web.bind.MissingServletRequestParameterException;@ControllerAdviceclass MissingServletRequestParameterExceptionHandler { @ExceptionHandler(MissingServletRequestParameterException.class) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleMissingParameter() { return "Your custom result"; }}
如果只想为特定控制器隐藏缺少的参数消息,则只需将handleMissingParameter
方法移至该控制器,而不创建ControllerAdvice。
HTTP状态405-具有Spring Security的Spring MVC不支持请求方法'POST'
如何解决HTTP状态405-具有Spring Security的Spring MVC不支持请求方法''POST''?
我不确定这是否有帮助,但是我遇到了同样的问题。
您正在使用带有CSRF保护的springSecurityFilterChain。这意味着通过POST请求发送表单时必须发送令牌。尝试将下一个输入添加到表单中:
<input type="hidden"
name="${_csrf.parameterName}"
value="${_csrf.token}"/>
解决方法
我使用freemarker模板作为视图部分创建了一个Spring mvc应用程序。在此尝试使用表格添加模型。我也在使用spring security这是代码
员工
<fieldset>
<legend>Add Employee</legend>
<form name="employee" action="addEmployee" method="post">
Firstname: <input type="text" name="name" /> <br/>
Employee Code: <input type="text" name="employeeCode" /> <br/>
<input type="submit" value=" Save " />
</form>
employeeController.java
@RequestMapping(value = "/addEmployee",method = RequestMethod.POST)
public String addEmployee(@ModelAttribute("employee") Employee employee) {
employeeService.add(employee);
return "employee";
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Spring MVC -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/appServlet/servlet-context.xml,/WEB-INF/spring/springsecurity-servlet.xml
</param-value>
</context-param>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<http security="none" pattern="/resources/**"/>
<!-- enable use-expressions -->
<http auto-config="true" use-expressions="true">
<intercept-url pattern="/login" access="isAnonymous()"/>
<intercept-url pattern="/**" access="hasRole(''ROLE_ADMIN'')" />
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
default-target-url="/"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password" />
<logout logout-success-url="/login?logout" />
<!-- enable csrf protection -->
<csrf />
</http>
<authentication-manager>
<authentication-provider user-service-ref="userDetailsService" >
<password-encoder hash="bcrypt" />
</authentication-provider>
</authentication-manager>
</beans:beans>
单击提交按钮时,将返回错误`
HTTP状态405-不支持请求方法“ POST”
`我在ftl和controller上都给出了POST方法。那为什么会这样呢?
java – 用于HTTP 400的Spring MVC自定义消息
我有几个如下所示的SprigMVC方法,返回ModelAndView或Responsebody.当用户向这些URL发出缺少所需参数的请求时,他们自然会收到消息“必需字符串参数’id’不存在”.
从安全角度来看,我想隐藏用户的详细描述消息.因此,黑客不容易知道缺少的参数,并且在没有任何描述的情况下会得到400错误.这可能是通过弹簧配置/ Spring Security实现的,或者我必须手动重构我的所有方法以某种方式返回自定义消息.
@RequestMapping(value = "/payment",method = RequestMethod.GET)
public ModelAndView getReponse(@RequestParam(value = "id",required = true)) {
return model;
}
@RequestMapping(value = "/status",method = RequestMethod.GET)
public @ResponseBody String getStatus(@RequestParam(value = "id",required = true) String id) {
return "string";
}
import org.springframework.web.bind.MissingServletRequestParameterException;
@ControllerAdvice
class MissingServletRequestParameterExceptionHandler {
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleMissingParameter() {
return "Your custom result";
}
}
如果要仅为特定控制器隐藏缺少的参数消息,只需将handleMissingParameter方法移动到此控制器,而不创建ControllerAdvice.
JavaEE开发之SpringMVC中的自定义消息转换器与文件上传
本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js、css这些静态文件的加载配置,以及服务器推送的两种实现方式。当然我们在服务器推送时,会用到jQuery的东西,所以我们先聊一下如何加载静态资源文件,然后我们再聊如何实现服务器推送。
下方给出了两种实现服务器推送的方式,一种是SSE(Server Send Event (服务端推送事件))另一种是基于Servlet异步处理的推送,下方会给出详细的实现方式,并且给出了两者的区别。
一、静态资源文件映射
静态资源文件映射在SpringMVC中的配置也是比较简单的、在我们spring的Config文件里边配置一下即可。下方就是我们在配置静态资源文件时所做的内容。
1、映射资源文件
首先我们在src/main/resources包下方创建了衣蛾assets文件,该文件下就存放着我们工程中所使用所有的静态资源文件。然后我们在Spring的配置文件中重写addResourceHandlers()方法,使用该方法来配置“assets”目录。
2、资源文件的引用
我们来创建一个jquery_test.jsp文件,该文件中引入了assets文件夹中js文件夹下的jquery.js文件。在jquery_test.jsp中就使用了jQuery的东西。下方就是该文件的所有内容。当然下方页面的功能比较简单,就是点击按钮,往HTML中动态的添加新的节点。具体代码如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="assets/js/jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#click").click(function(){ $("#test").append("<h2>Hello Spring MVC</h2>"); }); }); </script> <title>JQuery Demo</title> </head> <body> <input type="button" id="click" value="JQuery-TEST-Click me"/> <h2 id="test"></h2> </body> </html>
如果你想学习Java可以来这个群,首先是二二零,中间是一四二,最后是九零六,里面有大量的学习资料可以下载。
3、测试上述页面
当然要想访问上述页面,还得在Spring的配置文件中进行路由的配置。下方代码段就是Spring配置文件中静态文件路由的快速配置。
下方就是我们对相应路由的访问结果,如下所示。通过下方示例,我们可以看到jquery.js资源文件可以被正常的访问到。
二、Server Send Event (服务端推送事件)
Server Send Event简称SSE,使用该技术可以实现服务端像浏览器发送事件,也就是所谓的服务端的PUSH。本篇博客所聊的服务器推送技术的实现原理是当客户端向服务端发送请求时,服务端会抓住这个请求不放,等有数据更新的时候才返回给客户端。当客户端接收到消息后,再向服务端发送请求,周而复始。
服务端推送以及客户端发送的网络请求都是单向通信,后面的博客我们会介绍一种双向通信技术:WebSocket。本篇我们就先聊聊服务端的推送事件。
1.创建SSEController
首先我们创建一个普通的SpringMVC的Controller,命名为SSEContrller。下方就是SSEController类的具体实现,内容与普通的Controller差不多。只不过相应的方法在路由配置时,将produces属性的文本类型设置成“text/event-stream”即可。
在下方类的push()方法中,每500ms就会往客户端发送一个消息。消息的内容是当前时间,如下所示:
2、创建请求的JSP页面
创建好上述类后,我们就该创建测试上述Controller的JSP页面了,我们在相应的资源目录中创建一个sse.jsp页面。在sse.jsp页面中,我们将会使用到JavaScript中的EventSource对象来监听来着“/sse”路由的事件消息,当收到上述Controller发起的事件后,会在事件回调中做一些事情。当然,我们做的事情就是在HTML页面中添加新的节点,将事件响应的消息添加到HTML文本只能怪进行显示。
下方就是sse.jsp页面的具体代码。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="assets/js/jquery.js"></script> <script type="text/javascript"> if(window.EventSource){ var source = new EventSource('sse'); s = ''; source.addEventListener('message',function (e) { s += e.data+"<br/>"; $("#msgFromSSE").html(s); }); source.addEventListener('open',function (e) { console.log("连接打开"); },false); source.addEventListener('error',function (e) { if (e.readyState == EventSource.CLOSED) { console.log("连接关闭"); } else { console.log(e.readyState); } },false); } else { console.log("浏览器不支持SSE"); } </script> <title>SSE Demo</title> </head> <body> <h1>SSE-TEST</h1> <div id="msgFromSSE"></div> </body> </html>
3、测试我们的SSE
上面的事件发送端以及事件监听端的代码已实现完毕。接下来我们就要进行测试了。在测试之前,我们还要做一件事情,就是为我们的sse.jsp页面添加访问路由。我们就选择在Spring的配置文件中进行快速配置sse.jsp页面的路由。下方就是sse.jsp路由配置的相关代码:
registry.addViewController("/ssetest").setViewName("/sse");
配置完上述路由后我们就可以访问上述路由所对应的JSP页面了,下方就是具体的运行效果。从下方演示效果中,我们不难看出,每隔一段时间就会收到来自服务端的消息事件,具体如下所示:
三、Servlet中的异步推送
接下来我们来使用Servlet的异步处理以及Spring的任务计划(定时器)来实现事件的推送。当然本部分的最终实现效果与上述效果是一样的,只不过是实现方式不同。SSE是需要新式浏览器的支持,而Servlet的异步方法进行推送是跨浏览器的。接下来我们就来好好的来实现该技术点。
1、 实现Servlet中的异步推送前的配置
首先我们需要在Spring的配置文件中进行配置,是我们的Spring支持计划任务(Scheduleing),其实就是支持定时器。因为我们要定时的向客户端进行push,所以定时器的配置是必须的。
启动完定时器后,我们需要在Web初始化的类中开启Servlet的异步支持,如下所示。
2、创建Push Service
相关配置完成后,接下来我们要做的就是创建我们的Push Service。该Service就负责往客户端进行Push事件,Push Service的类对象就是我们相应Controller的依赖对象 ,稍后,我们将会将该依赖注入到相应的Controller中进行事件的Push。
下方就是PushService类的具体代码实现,需要使用@Service进行修饰。然后实例化一个DeferredResult对象负责传递事件消息。我们用到了@Scheduled注解来设定每次推送的间隔。
上面用到了@Service注解,我们可以点进去看一下Service注解中的内容。从其源码中我们不难看出其实@Service和@Component用法是一至的。@Service注解的实现如下所示:
3、创建调用PushService的Controller
创建完PushService后,接着就创建一个调用PushService的Controller类。下方这个ServletAsyncController就是负责调用PushService对象的Controller。其中使用了@Autowired注解来声明依赖注入的注入点。然后通过路由,路由到调用PushService的方法中即可。DeferredResult<String>就是推送事件的载体、而消息的类型是String类型。具体实现如下所示:
4、接收事件的JSP页面的实现
创建完Push Service以及负责推送的Controller后,接下来我们就该创建接收推送的客户端代码了。下方的代码比较简单,主要是使用jQuery来接收的推送事件。然后将推送的内容append到html中进行显示,如下所示:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="assets/js/jquery.js"></script> <script type="text/javascript"> deferred(); function deferred() { $.get('servlet_push',function (data) { $("#content").append(data+'<br/>'); deferred(); }); } </script> <title>Servlet_Async</title> </head> <body> <div id='content'></div> </body> </html>
给上述JSP页面配置路由的代码在此就省略了,和之前一样,给上述JSP页面在SpringConfig文件中配置一个路由,此处是“/async_push”,然后我们对该路由进行访问,下方就是访问效果,如下所示:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持编程小技巧!
您可能感兴趣的文章:
- JavaEE简介_动力节点Java学院整理
- ztree简介_动力节点Java学院整理
- 解决JavaEE开发中字符编码出现乱码的问题
- JavaEE微框架Spring Boot深入解读
- 别了Java EE! 正式更名为Jakarta
Java框架-Spring MVC理解003-spring MVC自身的创建
spring MVC自身的创建
1.整体结构介绍
springMVC中核心servlet的继承结构:
从结构图中可以看到,servlet的继承结构中一共有5个类。这里来说一下spring中的三个类。
这三个类直接实现三个接口:EnvironmentCapable、EnvironmentAware和Application-ContextAware。XXXAware在spring里表示对XXX可以感知,通俗点解释就是:如果在某个类里面想要使用spring的一些东西,就可以通过实现XXXAware接口告诉spring,spring看到后就会给你送过来,而接收的方式是通过实现接口唯一的方法set-XXX。
比如,有一个类想要使用当前的ApplicationContext,那么我们只需要让它实现ApplicationContextAware接口,然后实现接口中唯一的方法void setApplicationContext(ApplicationContext applicationContext)就可以了,spring会自动调用这个方法将applicationContext传给我们,我们只需要接收就可以了。EnvironmentCapable,顾名思义,当然就是具有Environment的能力,也就是可以提供Environment,所以EnvironmentCapable唯一的方法是Environment getEnvironment(),用于实现EnvironmentCapable接口的类,就是告诉spring它可以提供Environment,当spring需要Environment的时候就会调用其getEnvironment方法跟它要。
了解了Aware和Capable的意思,下面再来看一下ApplicationContext和Environment。前者相信大家都很熟悉了,后者是环境的意思。实际上在HttpServletBean中Environment使用的是Standard-Servlet-Environment(在createEnvironment方法中创建),这里封装了ServletContext,同时还封装了ServletConfig、JndiProperty、系统环境变量和系统属性,这些都封装到了其propertySources属性下。
为了让大家理解得更深刻,在前面项目的GoController中获取Environment,然后通过调试看一下。首先让GoController实现EnvironmentAware接口,这样spring就会将Environment传给我们,然后在处理请求的方法中加入断点,这样就可以查看spring传进来的内容了。
2.HttpServletBeen
我们知道Servlet创建时可以直接调用无参数的init方法。HttpServletBean的init方法如下:
可以看到,在HttpServletBean的init中,首先将Servlet中配置的参数使用BeanWrapper设置到DispatcherServle的相关属性,然后调用模板方法initServletBean,子类就通过这个方法初始化。
BeanWrapper:BeanWrapper是Spring提供的一个用来操作JavaBean属性的工具,使用它可以直接修改一个对象的属性。
public class User {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.beans.PropertyValue;
import com.excelib.common.User;
public class BeanWrapperTest {
public static void main(String[] args) {
User user=new User();
BeanWrapper bw=PropertyAccessorFactory.forBeanPropertyAccess(user);
bw.setPropertyValue("userName","张安");
System.out.println(user.getUserName());
PropertyValue prvalue=new PropertyValue("userName", "六六");
bw.setPropertyValue(prvalue);
System.out.println(user.getUserName());
}
}
这个例子首先新建了一个User对象,其次使用PropertyAccessorFactory封装成Bean-Wrapper对象,这样就可以使用了。
3.FrameworkServlet
首先看源码:他继承了httpservletBean,实现了ApplicationContextAware
他的初始化入口:
这里可以查看initWebApplicationContext()源码,他主要做了三件事。
①获取spring的根容器rootContext
②设置webApplicationContext并根据情况调用onrefresh()
③讲webApplicatiuonContext设置到servletContest中
4.DispatcherServlet
有兴趣的可以研究一下 源码。
5.总结
通过源码,了解Spring MVC自身的创建过程,Spring MVC中Servlet一共有三个层次,分别是HttpServletBean、FrameworkServlet和DispatcherServlet。HttpServletBean直接继承自Java的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性;FrameworkServlet初始化了WebApplicationContext,DispatcherServlet初始化了自身的9个组件。
FrameworkServlet初始化WebApplicationContext一共有三种方式,过程中使用了Servlet中配置的一些参数。
整体结构非常简单——分三个层次做了三件事,但具体实现过程还是有点复杂的。这其实也是spring的特点:结构简单,实现复杂。结构简单主要是顶层设计好,实现复杂的主要是提供的功能比较多,可配置的地方也非常多。当然,正是因为实现复杂,才让Spring MVC使用起来更加灵活,这一点在后面会有更深刻的体会。自己需要静下心来对照着源代码耐心地去看,我现在还有很多地方不是很明白,不在实际操作上应用不会了解很透彻,希望读者可以多留言交流。
我们今天的关于HTTP 400的Spring MVC自定义消息和springmvc自定义参数解析的分享就到这里,谢谢您的阅读,如果想了解更多关于HTTP状态405-具有Spring Security的Spring MVC不支持请求方法'POST'、java – 用于HTTP 400的Spring MVC自定义消息、JavaEE开发之SpringMVC中的自定义消息转换器与文件上传、Java框架-Spring MVC理解003-spring MVC自身的创建的相关信息,可以在本站进行搜索。
本文标签: