प्रतिक्रिया मुझे http प्रतिक्रिया सामग्री हैश के लिए वसंत सुरक्षा बढ़ाने और एक शीर्षलेख के अंदर परिणाम रखने की जरूरत है। मेरा दृष्टिकोण एक सर्वलेट फ़िल्टर बनाना है जो प्रतिक्रिया को पढ़ता है और उचित शीर्षलेख रखता है। फिल्टर एक अलग प्लगइन के माध्यम से वसंत सुरक्षा के साथ पंजीकृत है। कार्यान्वयन बड़े पैमाने पर से लिया गया है।Grails वसंत सुरक्षा, सर्वलेट फिल्टर, और
अंतिम सेटअप क्लाइंट को जेएसओएन आउटपुट करने के लिए नियंत्रक में "रेंडर" का उपयोग करता है जब पूरा सेटअप पूरी तरह से काम करता है। हालांकि, यदि एक ही डेटा "जवाब" के माध्यम से स्वरूपित किया गया है तो 404 ग्राहक को वापस कर दिया जाता है। मैं अंतर को समझाने के लिए एक नुकसान में हूँ।
संदर्भ के लिए सब कुछ है Grails संस्करण 2.3.11 और वसंत सुरक्षा कोर संस्करण 2.0-RC4
मेरी प्लगइन के doWithSpring के माध्यम से फिल्टर रजिस्टर
responseHasher(ResponseHasher)
SpringSecurityUtils.registerFilter(
'responseHasher', SecurityFilterPosition.LAST.order - 1)
मेरे फिल्टर कार्यान्वयन
public class ResponseHasher implements Filter{
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponseCopier wrapper = new HttpServletResponseCopier((HttpServletResponse)response);
chain.doFilter(request, wrapper);
wrapper.flushBuffer();
/*
Take the response, hash it, and set it in a header. for brevity sake just prove we can read it for now
and set a static header
*/
byte[] copy = wrapper.getCopy();
System.out.println(new String(copy, response.getCharacterEncoding()));
wrapper.setHeader("foo","bar");
}
@Override
public void destroy() {
}
}
HttpServletResponseCopier कार्यान्वयन। स्रोत से एकमात्र परिवर्तन केवल एक के बजाय लिखने के सभी 3 विधि हस्ताक्षर ओवरराइड करना है।
class HttpServletResponseCopier extends HttpServletResponseWrapper{
private ServletOutputStream outputStream;
private PrintWriter writer;
private ServletOutputStreamCopier copier;
public HttpServletResponseCopier(HttpServletResponse response) throws IOException {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on this response.");
}
if (outputStream == null) {
outputStream = getResponse().getOutputStream();
copier = new ServletOutputStreamCopier(outputStream);
}
return copier;
}
@Override
public PrintWriter getWriter() throws IOException {
if (outputStream != null) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
if (writer == null) {
copier = new ServletOutputStreamCopier(getResponse().getOutputStream());
writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()), true);
}
return writer;
}
@Override
public void flushBuffer() throws IOException {
if (writer != null) {
writer.flush();
} else if (outputStream != null) {
copier.flush();
}
}
public byte[] getCopy() {
if (copier != null) {
return copier.getCopy();
} else {
return new byte[0];
}
}
private class ServletOutputStreamCopier extends ServletOutputStream {
private OutputStream outputStream;
private ByteArrayOutputStream copy;
public ServletOutputStreamCopier(OutputStream outputStream) {
this.outputStream = outputStream;
this.copy = new ByteArrayOutputStream(1024);
}
@Override
public void write(int b) throws IOException {
outputStream.write(b);
copy.write(b);
}
@Override
public void write(byte[] b,int off, int len) throws IOException {
outputStream.write(b,off,len);
copy.write(b,off,len);
}
@Override
public void write(byte[] b) throws IOException {
outputStream.write(b);
copy.write(b);
}
public byte[] getCopy() {
return copy.toByteArray();
}
}
}
और अंत में वास्तविक आवेदन
@Secured()
def myAction() {
def thing = Thing.get(1) //thing can be any domain object really. in this case we created thing 1 in bootstap
//throws a 404
respond(thing)
/*
works as expected, output is both rendered
and sent to system out, header "foo" is in response
/*
//render thing as JSON
}
किसी भी अंतर्दृष्टि में मेरी नियंत्रक विधि की सराहना की होगी के रूप में मुझे समझ नहीं आता क्यों काम करेगा और जवाब नहीं होगा प्रस्तुत करना। इसके अतिरिक्त, मैं इस ज़रूरत को हल करने के लिए अन्य दृष्टिकोणों के लिए खुला हूं यदि मैं जो कोशिश कर रहा हूं वह केवल grails में काम नहीं करेगा। अग्रिम में धन्यवाद।
मुझे लगता है कि यह सामग्री बातचीत के साथ कुछ है: http://grails.github.io/grails-doc/2.3.x/guide/single.html #contentNegotiation। 'MyAction' को पैरामीटर' format = json' के साथ कॉल करने का प्रयास करें या 'स्वीकार करें' अनुरोध शीर्षलेख जोड़ें। – defectus
धन्यवाद। मैंने कोशिश की और इसका कोई असर नहीं पड़ा। मैं एक डीबगर संलग्न कर सकता हूं और देख सकता हूं कि यह कम से कम प्रतिक्रिया विधि के माध्यम से और जेसन रेंडरर में बना रहा है, वैध JSON को लात मार रहा है। मेरा (स्वीकार्य रूप से अज्ञानी) अनुमान है कि समस्या कहीं भी कहीं नीचे है –
आप डिफ़ॉल्ट Grails फ़िल्टर का उपयोग क्यों नहीं करते हैं और 'हेडर()' सेक्शन में नया हेडर डालते हैं? –